简体   繁体   中英

Prevent dirty read in mysql

I have a MySQL table

mysql> select * from test;
+----+--------+
| id | status |
+----+--------+
|  1 |  unread     |
+----+--------+

Suppose I am reading this application from Machine m1, m2, m3, m4 which are HA of each other.

What I want is :

If status == unread then any one(but only one) of m1, m2, m3, m4 can pick up this row changed its status to processing and process it further.

But what problem I am facing is of multiple dirty reads as m1, m2, m3, m4 simultaneously read status = unread and they simultaneously changed status to processing and start processing it.

How can I assure that only one among m1, m2, m3, m4 should read a row at a time ?

不确定为什么要使用java和多线程,因为您是从不同的机器访问数据库的,但是通常您可能需要SELECT ... FOR UPDATE

The question look likes about the data consistent of bussiness.

There are two approach can resolve the situation.

First,you can use the lock the row data by pessimistic lock when you access data. Like:

select ... from test for update

This approach is provided by the database system.

The second is optimistic lock.You should change your table format and you should add a column name version that is used identify the current data version.When you update the data,you should check the data version and increase the version.Like following:

currentVersion=select version ... from test where ...    //statement1

update status=processing,version=currentVersion+1 where version=currentVersion;    //statement2

Look your situation,all over of application will execute statement1 and get currentVersion,and when they execute the statement2, the statement2 will return how many rows has changed.But only one result is large than zero,the others is zero.So you can check it whether zero or not,and depend if execute your bussniess.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM