我有一个MySQL表
mysql> select * from test;
+----+--------+
| id | status |
+----+--------+
| 1 | unread |
+----+--------+
假设我正在从机器m1,m2,m3,m4读取此应用程序,它们是彼此的H.A.
我想要的是:
如果 status == unread
那么m1,m2,m3,m4中的任何一个(但只有一个)可以拿起这一行,将其状态改为processing
并进一步处理。
但我遇到的问题是多次脏读,同时m1,m2,m3,m4 读status = unread
,他们同时将状态更改为processing
并开始处理它。
我怎样才能确保m1,m2,m3,m4中只有一个应该一次读取一行?
答案 0 :(得分:0)
不确定为什么关于java
和多线程,因为您从不同的计算机访问数据库,但通常SELECT ... FOR UPDATE
是您可能需要的。
答案 1 :(得分:0)
问题看起来像商业数据一致。
有两种方法可以解决这种情况。
首先,您可以在访问数据时使用悲观锁来锁定行数据。 像:
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将返回已更改的行数。但只有一个结果大于零,其他结果为零。所以你可以检查它是否为零,并依赖于执行你的bussniess。