时间:2021-07-01 10:21:17 帮助过:4人阅读
mysql> insert into account(name,balance) values(‘lilei‘,450); Query OK, 1 row affected (0.00 sec) mysql> insert into account(name,balance) values(‘hanmei‘,16000); Query OK, 1 row affected (0.00 sec) mysql> insert into account(name,balance) values(‘lucy‘,2400); Query OK, 1 row affected (0.00 sec)
mysql> select * from account; +----+--------+---------+ | id | name | balance | +----+--------+---------+ | 1 | lilei | 450 | | 2 | hanmei | 16000 | | 3 | lucy | 2400 | +----+--------+---------+ 3 rows in set (0.00 sec)
1》我们先在一个命令行(下面称为命令行A)中,执行一段事务操作,但是不提交
mysql> begin; Query OK, 0 rows affected (0.00 sec) mysql> update account set balance=3000 where id=3; Query OK, 1 row affected (0.07 sec) Rows matched: 1 Changed: 1 Warnings: 0 mysql> select * from account; +----+--------+---------+ | id | name | balance | +----+--------+---------+ | 1 | lilei | 450 | | 2 | hanmei | 16000 | | 3 | lucy | 3000 | +----+--------+---------+ 3 rows in set (0.00 sec)
2》然后在另一个命令行(下面称为命令行B)中,进行一次修改操作:
mysql> update account set balance=3500 where id =3;
3》可以看到在命令行B中,并不会看到修改结构,因为命令行A中的事务会默认加上一个行锁,只要事务不停,行锁就一直保留:
4》此时我们在命令行A中进行提交,在命令行B中会看到提交返回:
5》但是命令行A提交了事务后,因为A本想将ID为3的用户【balance】修改为3000,可此时查看结果后发现:
6》所以此时A对ID为3的用户的修改未达到理想值
此时我们言归正传:
原子性(Atomicity)、一致性(Consistent)、隔离性(Isolation)、持久性(Durable)
1》更新丢失:两个事务同事操作相同数据,后提交的事务会覆盖先提交的事务处理结果,通过乐观锁就可以解决。(即文章开篇介绍的案例) 2》脏读:事务A读取到了事务B已经修改,但尚未提交的数据,如果事务B回滚,A读取的数据无效,不符合一致性。 3》不可重读:事务A读取到了事务B已经提交的修改数据,不符合隔离性。 4》幻读:事务A读取到了事务B提交的新增数据,不符合隔离性。
mysql> show variables like ‘tx_isolation‘; +---------------+-----------------+ | Variable_name | Value | +---------------+-----------------+ | tx_isolation | REPEATABLE-READ | +---------------+-----------------+
mysql> set tx_isolation=‘REPEATABLE-READ‘;(其他三种:READ-UNCOMMITTED,READ-COMMITTED,SERIALIZABLE)
mysql> set tx_isolation =‘READ-UNCOMMITTED‘;
1》脏读,不废话,直接上实例:
分析一下,上述指令,我们按顺序执行,可以看出因为事务B(右面)最后进行了回滚操作,但是事务A(左面)两次执行结果并不一样,造成了脏读情况。
2》不可重读,也不废话,线上案例:
分析来看,上述指令情况使得原子的一致性和隔离性均未实现,因为事务A还没有结束,所以两次所读数据应该一致,才可以保证事务实现一致性和隔离性。
3》幻读,先不墨迹,看案例就完了:
事务A一直处在一个事务内,但事务B缺新增了数据并提交了,而事务A两次查询结果不一致,从而该情况叫幻读。
因为【可串行化】的性能非常低,如果一个商城,开了【可串行化】的级别后,下个订单却要一分钟,这种用户体验你会接受么^ - ^
【MySQL】深入理解MySQL锁和事务隔离级别
标签:串行 lis value zab 问题 ODB table like 理解