道者编程


MYSQL事务并发处理的问题:脏读、不可重复读、幻读

MYSQL事务并发处理的问题:脏读、不可重复读、幻读


MYSQL5.5.X的版本默认引擎为:InNODB,在此之前是MyIASM。Innodb支持事务,MyIasm不支持事务。


一:脏读:事务A修改了某个值,但是未提交,这时候事务A又读取了这个值,事务A可能又把该值撤销(回滚),这时候的数据可能就是无用数据。这就叫脏读。这里有些同学可能就要问了,既然事务A没提交,事务B是怎么读取到的?如果MYSQL隔离级别设置ReadUnCommitted,这时候其他事务就可以读取到未提交的事务。(重点在于未提交)


二:不可重复读:事务A读取某个数据后,再次读取发现数据已经改变,两次或者多次读取同一数据数据不一致。(重点在于修改,数据本身对比

场景1:在同一个事务中,A查看自己工资有1000元,准备取出来,这个过程没有结束;此时财务人员在更新工资,把工资更新为2000,当A在取的时候,发现多了1000块,这个过程在这里看起来没啥问题,这就是不可重复读,下面看另外一个场景。

场景2:A今天查看自己卡了有1000,于是打算消费,此时A的老婆B正在网上转账,当A消费的那一刻,发现卡里钱不够了,明明刚才还有1000,为什么没了呢?因为老婆刚才转出去了,这就尴尬了。要避免这种情况,就要采用事务隔离级别,Repeatable read 重复读。在A读取的时候(事务开始,但还未结束。),这个时候A的老婆B不能转账,除非A的事务结束。


三:幻读:相同的查询在事务执行后,发现得到的结果不一样,明明执行了5个操作,却发现多了N个,或少了N个,就好像发生了幻觉一样。(重点在于新增和删除,数据条数对比

场景1:财务今天修改了员工表的一些记录,同时,其他人事又添加了一名新员工进来,此时财务人员就发现,怎么多了几条记录?


附录:


此图转自互联网

MySQL 默认的级别是:Repeatable read 可重复读,其他主流数据库,如Oracle;SQLServer默认级别为:Read committed


四:修改隔离级别:

1:全局修改;my.cnf

1 #可选参数有:READ-UNCOMMITTED, READ-COMMITTED, REPEATABLE-READ, SERIALIZABLE.
2 [mysqld]
3 transaction-isolation = REPEATABLE-READ #mysql默认就是这个
 2:当前修改,重启mysql后失效

mysql> set tx_isolation='read-committed';
 


最新评论:
我要评论:

看不清楚


链接