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