
课程咨询: 400-996-5531 / 投诉建议: 400-111-8989
认真做教育 专心促就业
随着互联网的不断发展,越来越多的Java程序员都在学习MySQL数据库开发等编程技术知识,而本文我们就通过案例分析来简单了解一下,并发事务问题分析与解决方法。
1.并发事务产生的问题
并发事务会产生下面三个问题:
脏读
定义:一个事务读到其他事务未提交的数据。
可以看出,在事务2修改完数据,没有提交的情况。事务1已经读到事务2新修改的数据,这种情况就属于脏读。
不可重复读
定义:一个事务读取到其他事务修改过的数据。
可以看出,在事务2修改完数据,并提交事务后。事务1二次查询已经读到事务2新修改的数据,这种情况就属于不可重复读。
幻读
定义:一个事务读取到其他事务新插入的数据。
可以看出,在事务2插入完数据,并提交事务后。事务1二次查询已经读到事务2新插入的数据,这种情况就属于幻读。
2.快照读和当前读
再普及一下快照读和当前读。
快照读:读取数据的历史版本,不对数据加锁。
例如:select
当前读:读取数据的新版本,并对数据进行加锁。
例如:insert、update、delete、selectforupdate、selectlockinsharemode。
3.再谈幻读问题
MySQL在RepeatableRead(可重复读)隔离级别下,到底有没有解决幻读的问题?
只能说是部分解决了幻读问题。
先,在快照读的情况下,是通过MVCC(复用读视图)解决了幻读问题。
想详细了解MVCC和读视图,可以翻一下上篇文章。
先手动设置一下MySQL的隔离级别为可重复读:
SETSESSIONTRANSACTIONISOLATIONLEVELREPEATABLEREAD;
执行测试用例,验证一下:
可以看出,事务1的两次查询,得到的结果一致,并没有查到事务2新插入的数据。
原因是,在可重复读隔离级别下,一次快照读的时候,生成了一个读视图。二次快照读的时候,复用了一次生成的读视图,所以两次查询得到的结果一致。
所以,在快照读的情况下,可重复读隔离级别是解决了幻读的问题。
再测试一下,在当前读的情况下,可重复读隔离级别是否解决幻读问题:
可以看出,事务1的两次查询,得到的结果不一致。在事务2插入数据,并提交事务后。事务1的二次执行当前读(加了forupdate)的时候,读到了事务2新插入的数据。
原因是,在可重复读隔离级别下,每次执行当前读会生成一个新的读视图,所以能读到其他事务新插入的数据。
所以,在当前读的情况下,可重复读隔离级别是没有解决了幻读的问题。
在执行上面的测试用例的时候,我忽然想到一个问题,既然selectforupdate的当前读,出现了幻读问题,是不是其他的当前读也会复现幻读问题,比如insert。
【免责声明】:本内容转载于网络,转载目的在于传递信息。文章内容为作者个人意见,本平台对文中陈述、观点保持中立,不对所包含内容的准确性、可靠性与完整性提供形式地保证。请读者仅作参考。更多内容请加danei0707学习了解。欢迎关注“达内在线”参与分销,赚更多好礼。