Q:什么是事务?
A:指的是一组 SQL 语句或者一个执行单位,要么全部执行成功,提交到数据库,要么中间出错全部回滚,不影响数据库。
Q:事务的用途有哪些?
A:①、确保尚未全部完成的操作不会影响到数据库,以致不会让数据库处于部分更新(不一致)状态;②、确保在操作某个数据行(MySQL 会对涉及到的资源进行锁定)时,不会被其他客户端修改。
Q:事务的特性有哪些?
A:具有 ACID 四种特性。
①、Atomic(原子性):构成事务的所有语句是一个独立的逻辑单元,也就是你不能只执行所有语句中的一部分语句。
②、Consistent(一致性):数据库在事务的执行前后必须是一致的。也就是说一个表中的 ID ,必须在另一个表中找到,否则回滚。
③、Isolated(独立性):事务之间不应该相互影响,也就是在并发执行时,事务能够挨个执行。
④、Durable(持久性):当事务执行成功完成时,会永久性地记录到数据库中。
注意:要想使用事务,就必须选用一种支持事务处理的存储引擎。如 InnoDB。
利用事务保证语句安全执行
MySQL 默认是自动提交到数据库(永久性保存)
-- 查看执行事务的方法:1:开启自动提交 0:禁用自动提交
SELECT @@global.autocommit;
SELECT @@session.autocommit;
SELECT @@autocommit;
两种执行事务的方法:
1、start transaction(或 begin)语句
-- ①、挂起自动提交模式,开启一个新的事务。
START TRANSACTION;
-- ②、执行构成本次事务的各条 SQL 语句
INSERT INTO t SET name = 'zhangsan';
INSERT INTO t SET name = 'lisi';
-- ③、用 COMMIT 语句永久性保存这些更改 或者 用 ROLLBACK 语句撤销所有更改。
COMMIT;
SELECT * FROM t;
注意:它是开启一个新的事务,在事务被提交或回滚之后,该模式将恢复到开始本次事务的 START TRANSACTION 语句被执行之前的状态(如果自动提交模式原来是激活的,结束事务将让你回到自动提交模式;如果它原来是禁用的,结束当前事务将开始下一个事务)
2、SET 语句直接操作自动提交模式的状态
-- ①、禁用自动提交
SET AUTOCOMMIT = 0;
-- ②、执行构成本次事务的各条 SQL 语句
INSERT INTO t SET name = 'zhangsan';
INSERT INTO t SET name = 'lisi';
-- ③、用 COMMIT 语句永久性保存这些更改 或者 用 ROLLBACK 语句撤销所有更改。
COMMIT;
-- ④、开启自动提交
SET AUTOCOMMIT = 1;
注意:是在当前 session 禁用自动提交事物。
使用事务保存点
MySQL 可以对事物进行部分回滚(即回滚到保存点)。
CREATE TABLE t(i INT) ENGINE = InnoDB;
START TRANSACTION ;
INSERT INTO t VALUES (1);
SAVEPOINT my_savepoint; -- 保存点
INSERT INTO t VALUES (2);
ROLLBACK TO SAVEPOINT my_savepoint; -- 回滚到保存点
INSERT INTO t VALUES (3);
COMMIT ;
SELECT * FROM t; -- 1 、 3
事务隔离
在数据库操作中,为了有效保证并发读取数据的正确性,提出的事务隔离级别。
在多个事务并发操作的过程中,如果控制不好隔离级别,就有可能产生脏读、不可重复读或者幻读等读现象。
- 脏读:一个事务读取到了另一个事务未提交的数据操作结果。危险之处:很可能所有的操作都被回滚。
- 不可重复读:同一个事务使用同一条 SELECT 语句在每次读取时得到的结果都不一样。
- 幻影行:一个事务突然看到一个以前没有见过的数据行。某个事务在 SELECT 之后,另一个事务插入一条新的数据行,如果第一个事务再执行同样的一条 SELECT 语句,则可能会看到这个新增行,而它其实是一个幻影。
为了解决以上这些问题,InnoDB 存储引擎提供了 4 种事务隔离级别。
- READ UNCOMMITTED:允许某个事务看到其他事务尚未提交的行修改。
- READ COMMITTED:只允许某个事务看到其他事务已经提交的行修改。
- REPEATABLE READ:如果某个事务两次执行同一条 SELECT 语句,其结果是可重复的。也就是说,即使有其他事务在同时插入或修改行,这个事务所看到的结果也是一样的。
- SERIALIZABLE:对于某个事务正在查看的行,只有等到该事务完成才能被其他事务所修改。

InnoDB 存储引擎默认的隔离级别是 REPEATABLE READ。
修改它的两种方式:①、在服务器启动时使用 --transaction-isolation 选项;②、在服务器运行时使用 SET TRANSACTION 语句
-- 查看隔离级别
select @@global.tx_isolation;
select @@session.tx_isolation;
SELECT @@tx_isolation;
-- 改变全局隔离级别,作用于后续的所有客户端连接
SET GLOBAL TRANSACTION ISOLATION LEVEL READ UNCOMMITTED ;
-- 改变当前会话里的所有事务的隔离级别
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED ;
-- 改变下一个事务的隔离级别
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED ;
最后:四种事务隔离级别从隔离程度上越来越高,但同时在并发性上也就越来越低。我们应该在开发过程中根据业务需要选择最合适的隔离级别。
网友评论