mysql InnoDB 并发事务 更新丢失
同一时间多个事务并发更新同一行数据,且更新后的数据是基于更新前的数据,造成了更新丢失的问题。
我将事务的隔离级别设置为了最高的 SERIALIZABLE ,但发现并不能解决这个问题。
在并发事务处理带来的问题中,“更新丢失”通常应该是完全避免的。但防止更新丢失,并不能单靠数据库事务控制器来解决,需要应用程序对要更新的数据加必要的锁来解决,因此,防止更新丢失应该是应用的责任。
这段话是引用的别人文章中的话,不是很理解。
我的想法有两种:
1、在后台程序中将并发的事务强制变为同步串行执行,但总感觉哪里不妥
2、控制数据库让多个事务对同一行数据进行操作时,不论读写,直接锁死该行数据,先来的事务获得读写的权限,事务完成,下一个事务再获取读写的权限进行操作,但问题如何实现啊?
请各位帮忙解疑,如果你能详细说明下在 node.js 、mysql、sequelize 中如何处理这样更好。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
会话的隔离级别设置为serializable的时候,其他会话对该表的写操作将被挂起;但是还是可以读取数据的,因此根据读取的数据做更新还可能会有问题。
应用程序中为了防止核心数据被并发修改,一般在查询数据的语句中增加for update的选项,从数据库层面避免造成同一条数据被两个事务同时进行操作。
我怀疑兄弟你没有显示开启事务吧? mysql innodb支持行锁,不论你的事务隔离级别是什么样的,只要你开启事务修改了一行数据还没有提交,你就获得了这行数据的写锁,其他事务就不能再修改这条记录。事务隔离级别只是确认其他事务能不能读取到你修改过未提交的数据记录而已,当你修改完成提交事务,其他事物才能获得这行记录的修改权限,才能执行修改操作,换句话说,对于innodb的某一行记录而言,多个会话对它的更新操作也只能是串行的,只有前一个事务修改完成并且提交,后一个事务才能进行更新操作。所以题主说的更新丢失的情况,要么是没有提交,要么是没有显示开启事务,记录被连续多个会话更新,再就是系统崩溃也会丢失未完成的事务操作。
select * ... for update
详细解释和代码:https://crossoverjie.top/2017...