Mysql隔离级别学习整理
Mysql隔离级别查看
查看会话隔离级别
1 | select @@transaction_isolation |
查看系统隔离级别
1 | select @@global.transaction_isolation |
Mysql隔离级别修改
Mysql默认的隔离级别是可重复读(repeatable read)。
可以在my.inf
文件中修改默认的隔离级别:
1 | transaction-isolation = {READ-UNCOMMITTED | READ-COMMITTED | REPEATABLE-READ | SERIALIZABLE} |
也可以使用SET TRANSACTION
语句改变单个会话或者所有新连接的隔离级别,语法如下:
1 | SET [SESSION | GLOBAL] TRANSACTION ISOLATION LEVEL {READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE} |
四种隔离级别
隔离级别 | 脏读 | 不可重复读 | 幻读 |
---|---|---|---|
读未提交(read uncommitted) | 可能 | 可能 | 可能 |
读已提交(read committed) | 不可能 | 可能 | 可能 |
可重复读(repeatable read) | 不可能 | 不可能 | 可能 |
可串行化(serializable) | 不可能 | 不可能 | 不可能 |
示例
新建一个表:
1 | CREATE TABLE `test` ( |
read uncommitted级别出现脏读
当一个事务修改了数据且未提交,另一个事务可以读到这个未被提交的数据。
事务1:
事务2:
可以看到,事务2能够读到事务1未提交的数据。
read committed级别出现不可重复读
在同一个事务内,多次读取同一个数据,此时事务还没有完成。另一个事务在前一个事务两次读取之间修改了数据并提交,导致前一个事务读到的数据不一样,因此称为不可重复读。
事务1(事务内第一次读)
事务2
事务1(事务内第二次读)
可以看到,由于事务2修改了数据,导致事务1两次读到的数据不一致。
repeatable read级别的可重复读
事务1(事务内第一次读)
事务2
事务1(事务内第二次读)
可以看到,尽管事务2插入了新的数据,但是在事务1中两次读到的数据是一致的。
repeatable read级别出现的幻读
幻读现象1:
1 | session1: session2: |
幻读现象2:
1 | session1: session2: |
加锁
通过加锁来防止幻读
1 | session1: session2: |
通过加锁读来获得其他事务提交的结果
1 | session1: session2: |