MySQL事务实现原理

MySql事务实现原理--参考极客时间专栏《MySQL实战45讲》,博客

 

1.事务的基本要素(ACID)

原子性(Atomicity):事务内的操作要嘛全部完成,要嘛全部回滚。

一致性(Consistency):事务执行的前后都是合法的数据状态,不会违反任何的数据完整性。

隔离性(Isolation):主要是事务之间的相互的影响,根据隔离有不同的影响效果。

持久性(Durability):事务一旦提交,就会体现在数据库上,不能回滚。

 

2.事务并发的问题

脏读:比如事务A执行的过程中,读到了事务B未提交的内容。

不可重复度:指一个事务在前后两次查询的结果不一致。

幻读:幻读是指前后两次相同条件下的查询,后一次查询读到了前一次查询没有的行数据。

特别注意的是:在不可重复读的隔离级别下,普通查询是不会出现幻读的,因为都是快照读,只有在当前读,也就是select语句后面加for update查询的时候出现,幻读的解决办法,后面会有。

 

3.事务的隔离级别

(1)读未提交

存在问题:脏读,不可重复读,幻读。

(2)读已提交

存在问题:不可重复读,幻读.

实现依赖于一致性视图(MVCC实现):查询只承认在语句启动前就已经提交完成的数据。

(3)可重复读

存在问题:幻读,使用当前读解决读已提交隔离级别的不可重复读。

实现依赖于一致性视图(MVCC实现):查询只承认在事务启动前就已经提交完成的数据;

幻读的问题:

1.破坏语义

select * from test_table where col_1 = 1 for update;

这条sql语句的本意是要把test_table的col_1 为1的行锁住,不允许别人事务对这些行进行操作。

假设test_table中id为1的行,col_1的值不为1

有以下两个语句:

update test_table set col_1 = 1 where id = 1

update test_table set col_2 = 12 where id = 1

 对test_table的col_1 为1的行进行修改,违背了将这些行锁住的语句。

2.数据一致性问题

主要体现在各个事务提交的时间点不确定,各个事务之间的语句会有影响,从而写到binlog的逻辑语句与表达的语义不一致。

即使对所有的行加入了锁,也会出现不一致,因为可能要插入心的行。

 

幻读解决办法:

引入间隙锁,会锁住区间,跟间隙锁存在冲突关系的,是“往这个间隙中插入一个记录”这个操作。间隙锁和行锁合称 next-key lock。

间隙锁的困扰:有可能引发死锁。主要体现在两个事务互相等待对方的间隙锁。

解决办法:隔离级别设为读已提交,同时为了解决数据不一致问题,binlog的格式设置为row。

选择哪一个事务隔离级别,具体问题具体分析。

 

(4)串行化

存在问题:没有幻读,脏读,不可重复读的问题,但是由于是串行,性能非常差。

你可能感兴趣的:(MySql)