在mysql

时间:2017-08-16 01:50:24

标签: java mysql database multithreading transactions

我有一个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中只有一个应该一次读取一行

2 个答案:

答案 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。