mysql事务隔离级别与产生的现象

测试环境

centos7.7+mysql5.6.48

测试表

mysql> show  create table aa;
+-------+--------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table                                                                                                             |
+-------+--------------------------------------------------------------------------------------------------------------------------+
| aa    | CREATE TABLE `aa` (
  `id` int(11) DEFAULT NULL,
  `name` varchar(100) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |

READ-UNCOMMITTED

设置隔离级别read-uncommitted

mysql> set global tx_isolation='READ-UNCOMMITTED';
Query OK, 0 rows affected (0.00 sec)

mysql> show variables like '%tx_isolation%';
+---------------+------------------+
| Variable_name | Value            |
+---------------+------------------+
| tx_isolation  | READ-UNCOMMITTED |

事务T1执行一个查询操作,返回值如下
mysql> begin;
mysql> select * from aa;
±-----±-----+
| id | name |
±-----±-----+
| 1 | aa |
| 2 | bb |
±-----±-----+
事务T2执行一条插入操作,但不进行提交

mysql> begin;
mysql> insert into aa values(3,‘cc’);

事务T1接着执行查询操作,这里能查询到事务T2执行的插入但没提交的记录

mysql> select * from aa;
±-----±-----+
| id | name |
±-----±-----+
| 1 | aa |
| 2 | bb |
| 3 | cc |

接着事务T2执行回滚操作
mysql> rollback;
事务T1再次查询,则查询不到ID=3的记录
mysql> select * from aa;
±-----±-----+
| id | name |
±-----±-----+
| 1 | aa |
| 2 | bb |
±-----±-----+
说明:在未提交读的事务隔离模式下,会产生脏读现象。

READ-COMMITTED

mysql> set  tx_isolation='READ-COMMITTED';
mysql> show variables like '%tx_isolation%';
+---------------+------------------+
| Variable_name | Value            |
+---------------+------------------+
| tx_isolation  | READ-COMMITTED |
+---------------+------------------+

事务T1执行查询操作,返回结果如下,但事务未提交

mysql> begin;
mysql> select * from aa where id>=1 and id<=2;
±-----±-----+
| id | name |
±-----±-----+
| 1 | aa |
| 2 | bb |
±-----±-----+

事务T2修改ID=1的name为cc并提交

mysql> begin;
mysql> update aa set name=‘cc’ where id=1;
mysql> commit;

扫描二维码关注公众号,回复: 11886768 查看本文章

事务T1继续执行相同的查询操作,发现在同一个事务里,相同的记录被查询两次得到的结果不一致

mysql> select * from aa where id>=1 and id<=2;
±-----±-----+
| id | name |
±-----±-----+
| 1 | cc |
| 2 | bb |
±-----±-----+
mysql> commit;
说明:在事务隔离级别为READ-COMMITTED的模式下,在同一个事务里,相同的记录被查询两次得到的结果不一致,出现了幻读。

REPEATABLE-READ

mysql> show variables like '%tx_isolation%';
+---------------+-----------------+
| Variable_name | Value           |
+---------------+-----------------+
| tx_isolation  | REPEATABLE-READ |
+---------------+-----------------+

事务T1执行范围查询操作,返回下面两条记录
mysql> begin;
mysql> select * from aa where id>=1 and id<=4;
±-----±-----+
| id | name |
±-----±-----+
| 1 | cc |
| 2 | bb |
±-----±-----+
事务T2执行一条查询操作

mysql> begin;
mysql> insert into aa values(3,‘dd’);
mysql> commit;

事务T1在同一个事务执行相同的查询操作,看看是否能查询到新记录

mysql> select * from aa where id>=1 and id<=4;
±-----±-----+
| id | name |
±-----±-----+
| 1 | cc |
| 2 | bb |
±-----±-----+

mysql> commit;
结果:在同一个事务里,两次查询到的结果是一致的,这里应该是能查询到ID=3的记录,但为什么没有查询到呢
提交T1事务后,再次查询呢
mysql> select * from aa where id>=1 and id<=4;
±-----±-----+
| id | name |
±-----±-----+
| 1 | cc |
| 2 | bb |
| 3 | dd |
±-----±-----+
3 rows in set (0.00 sec
结果:能查询到ID=3的新记录。

说明:在repeatable-read事务隔离模式下,在事务执行过程中,另一个事务会将新记录添加到正在执行读取操作的事务中,会发生幻读,当执行select * from where没有对范围进行锁定的情况下,则可能会发生这样的情况,但上述的例子中并没有出现这种情况,是因为mysql增加了间隙锁来防止幻读,所以在repeatable-read事务隔离模式下看不到。

总结

1、修改事务隔离级别,永久生效
[mysqld]
transaction-isolation = REPEATABLE-READ
transaction-read-only = OFF

2、set global tx_isolation设置事务隔离级别失败,set tx_isolation则可以

参考资料

https://dev.mysql.com/doc/refman/5.6/en/set-transaction.html

猜你喜欢

转载自blog.csdn.net/weixin_41561946/article/details/108230717