1. 什么是事务。
事务就是一类操作的集合。这些操作要么都成功,有一个失败就会都失败,是一个不可分割的工作单位。(一荣俱荣,一损俱损)。
2. 事务的特性
2.1 原子性(Atomicity)
事务为一组不可分割的工作单位,要么都成功,有一个失败,都失败。
2.2 一致性(Consistency)
事务执行操作的结果,会从一个一致性状态变为另一个一致性状态。实现一致性主要通过原子性,隔离性,持久性。
2.3 隔离性(Isolation)
一个事务的执行不能被其他事务干扰。即一个事务的内部操作及使用的数据对其他并发事务的隔离的,并发执行的各个事务之间不能互相干扰。
2.4 持久性(Durability)
事务提交之后,对数据的改动是永久性的。
3. 并发事务出现的问题
3.1 脏读
3.2 不可重复读
同一个事务之内,多次读取数据应该相同。
3.3 幻读
幻读只会出现在并发事务插入或者删除时。
4.事务的隔离级别
4.1 读未提交(READ UNCOMMITTED)
select @@tx_isolation; #查看当前事务的隔离级别
select @@autocommit; #事务的自动提交 1开启,0关闭
A:set global transaction isolation level read uncommitted; #设置隔离级别
A:set autocommit=0; #关闭事务的自动提交
A: start transaction; #开始事务
B:set autocommit=0; #关闭事务的自动提交
B: start transaction; #开始事务
A: update tran set name='aaa';
B: select * from trans;
A: rollback;
B: select * from trans;
B: commit;
出现的问题:脏读,不可重复读,幻读;
4.2 读已提交(READ COMMITTED)
A: set session transaction isolation level read committed;
A: start transaction;
B: set session transaction isolation level read committed;
B: start transaction;
A: update tran set name='aaa';
B: select * from tran;
A: commit;
B: select * from tran;
B: commit;
出现的问题:不可重复读,幻读
4.3 可重复读(REPEATABLE READ)
A: set session transaction isolation level repeatable read;
A: start transaction;
B: set session transaction isolation level repeatable read;
B: start transaction;
A: update tran set name='bbb';
B: select * from tran;
A: commit;
B: select * from tran;
A: start transaction;
A: insert into tran values(4,'ccc');
A: commit;
B: insert into tran values(4,'ccc');
出现问题:幻读
4.4 序列化(Serializable)
事务串行化执行,不会出现任何问题
脏读 | 不可重复读 | 幻读 | |
读未提交 | √ | √ | √ |
读已提交 | √ | √ | |
可重复读 | √ | ||
序列化 |
5.锁机制
Innodb引擎默认为行锁,如果某行数据没有使用索引的情况下,行锁会升级为表锁。
加共享锁:sql语句 lock in share mode;
加排它锁:sql语句 for update;
myISAM引擎默认为表锁。
加锁方式,lock table table_name read/write;
解锁方式:unlock tables;
共享锁(S锁):多个事务可以同时对一个数据或表进行读取,不能进行除读取之外的操作,更不能加写锁。
排它锁(X锁):某个事务为某个表或数据行加了写锁,其他事务就不能进行添加锁包括读锁。
共享锁S | 排它锁X | 无锁 | |
共享锁S | Y | N | Y |
排它锁X | N | N | Y |
无锁 | Y | Y | Y |
5.1 一级封锁协议
一级封锁协议,事务T在修改数据R之前必须先对其加X锁,知道事务结束才释放锁。可以防止丢失修改。
5.2 二级封锁协议
在一级封锁协议的基础上增加事务T对读取数据R之前必须先对其加S锁,读完就释放S锁。
5.3 三级封锁协议
在一级封锁协议的基础上,增加事务T在读取数据R之前必须先对其加S锁。直到事务结束才释放。