簡體   English   中英

防止在mysql中臟讀

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM