[英]Prevent dirty read in mysql
我有一个MySQL表
mysql> select * from test;
+----+--------+
| id | status |
+----+--------+
| 1 | unread |
+----+--------+
假设我正在从彼此为HA的机器m1,m2,m3,m4中读取此应用程序。
我想要的是:
如果 status == unread
则m1,m2,m3,m4中的任何一个(但只有一个)可以提取该行,将其状态更改为processing
并进一步processing
。
但是我面临的问题是多个脏读,因为m1,m2,m3,m4同时读取status = unread
读取,并且它们同时将状态更改为processing
并开始处理它。
我如何确保在m1,m2,m3,m4中只有一次可以读取一行 ?
不确定为什么要使用java
和多线程,因为您是从不同的机器访问数据库的,但是通常您可能需要SELECT ... FOR UPDATE
。
问题看起来像关于业务一致性的数据。
有两种方法可以解决这种情况。
首先,访问数据时可以使用悲观锁来锁定行数据。 喜欢:
select ... from test for update
该方法由数据库系统提供。
第二个是乐观锁。您应该更改表格式,并添加用于标识当前数据版本的列名version
。更新数据时,应检查数据版本并增加版本。例如:
currentVersion=select version ... from test where ... //statement1
update status=processing,version=currentVersion+1 where version=currentVersion; //statement2
看你的情况,整个应用程序都将执行statement1并获得currentVersion,而当他们执行statement2时,statement2将返回已更改的行数。但是只有一个结果大于零,其他结果为零,因此您可以检查它是否为零,并取决于是否执行您的业务。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.