我是靠谱客的博主 炙热吐司,最近开发中收集的这篇文章主要介绍mysql更新丢失_程序员最容易犯的错:mysql更新丢失的问题,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

引用:《MySQL技术内幕:InnoDB存储引擎(第2版)》

丢失更新是另一个锁导致的问题,简单来说其就是一个事务的更新操作会被另一个事务的更新操作所覆盖,从而导致数据的不一致。例如:

1)事务T1将行记录r更新为v1,但是事务T1并未提交。

2)与此同时,事务T2将行记录r更新为v2,事务T2未提交。

3)事务T1提交。

4)事务T2提交。

但是,在当前数据库的任何隔离级别下,都不会导致数据库理论意义上的丢失更新问题。这是因为,即使是READ UNCOMMITTED的事务隔离级别,对于行的DML操作,需要对行或其他粗粒度级别的对象加锁。因此在上述步骤2)中,事务T2并不能对行记录r进行更新操作,其会被阻塞,直到事务T1提交。

虽然数据库能阻止丢失更新问题的产生,但是在生产应用中还有另一个逻辑意义的丢失更新问题,而导致该问题的并不是因为数据库本身的问题。实际上,在所有多用户计算机系统环境下都有可能产生这个问题。简单地说来,出现下面的情况时,就会发生丢失更新

1)事务T1查询一行数据,放入本地内存,并显示给一个终端用户User1。

2)事务T2也查询该行数据,并将取得的数据显示给终端用户User2。

3)User1修改这行记录,更新数据库并提交。

4)User2修改这行记录,更新数据库并提交。

显然,这个过程中用户User1的修改更新操作“丢失”了,而这可能会导致一个“恐怖”的结果。设想银行发生丢失更新现象,例如一个用户账号中有10 000元人民币,他用两个网上银行的客户端分别进行转账操作。第一次转账9000人民币,因为网络和数据的关系,这时需要等待。但是这时用户操作另一个网上银行客户端,转账1元,如果最终两笔操作都成功了,用户的账号余款是9999人民币,第一次转的9000人民币并没有得到更新,但是在转账的另一个账号却会收到这9000元,这导致的结果就是钱变多,而账不平。也许有读者会说,不对,我的网银是绑定USB Key的,不会发生这种情况。是的,通过USB Key登录也许可以解决这个问题,但是更重要的是在数据库层解决这个问题,避免任何可能发生丢失更新的情况。要避免丢失更新发生,需要让事务在这种情况下的操作变成串行化,而不是并行的操作。即在上述四个步骤的1)中,对用户读取的记录加上一个排他X锁。同样,在步骤2)的操作过程中,用户同样也需要加一个排他X锁。通过这种方式,步骤2)就必须等待一步骤1)和步骤3)完成,最后完成步骤4)。

7b658d367a66b8bdd89d873209930d20.png

有读者可能会问,在上述的例子中为什么不直接允许UPDATE语句,而首先要进行SELECT…FOR UPDATE的操作。的确,直接使用UPDATE可以避免丢失更新问题的产生。然而在实际应用中,应用程序可能需要首先检测用户的余额信息,查看是否可以进行转账操作,然后再进行最后的UPDATE操作,因此在SELECT与UPDATE操作之间可能还存在一些其他的SQL操作。程序员可能在了解如何使用SELECT、INSERT、UPDATE、DELETE语句后就开始编写应用程序。因此,丢失更新是程序员最容易犯的错误,也是最不易发现的一个错误,因为这种现象只是随机的、零星出现的,不过其可能造成的后果却十分严重。

欢迎关注,坚持更新

最后

以上就是炙热吐司为你收集整理的mysql更新丢失_程序员最容易犯的错:mysql更新丢失的问题的全部内容,希望文章能够帮你解决mysql更新丢失_程序员最容易犯的错:mysql更新丢失的问题所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(52)

评论列表共有 0 条评论

立即
投稿
返回
顶部