![](/img/trans.png)
[英]How to ensure consistency with concurrent requests on Appengine entities with objectify?
[英]How do I ensure data consistency in this concurrent situation?
問題是這樣的:
String name
- 該名稱存在於表中,數據庫應返回該行的id,該名稱尚不存在,應插入名稱並返回id。 name
實例 - 即。 名稱必須是唯一的 如何確保線程1不會同時插入name1
,因為線程2也嘗試插入name1
? 換句話說,如何保證並發環境中name
的唯一性? 這也需要盡可能高效 - 這有可能成為一個嚴重的瓶頸。
我正在使用MySQL和Java。
謝謝
假設name列上有唯一約束,則每個insert
都將獲得一個鎖。 任何嘗試同時插入第二次的線程將等到第一次insert
成功或失敗(tx提交或回滾)。
如果第一個事務成功,則第二個事務將因唯一鍵沖突而失敗。 然后你知道它已經存在了。
如果每個事務有一個插入,那么它就是。 如果每個事務有多個插入,則可能會死鎖。
每個線程都將傳遞一個String名稱 - 該名稱存在於表中,數據庫應返回該行的id,該名稱尚不存在,應插入名稱並返回id。
總而言之,算法是這樣的:
1 read row with name
2.1 if found, return row id
2.2 if not found, attempt to insert
2.2.1 if insert succeeds, return new row id
2.2.2 if insert fails with unique constraint violation
2.2.2.1 read row with name
2.2.2.2 read should succeed this time, so return row id
因為唯一索引可能存在高爭用 , insert
可能會阻塞一段時間。 在這種情況下,交易可能會超時 。 進行一些壓力測試,並調整配置,直到它與您的負載正常工作。
此外,您應該檢查是否獲得了唯一約束違例異常或其他一些異常。
而且,這僅在每個事務有一個插入時才有效,否則可能會死鎖 。
此外,您可以嘗試使用“ select * for update
”讀取步驟1中的行。 在這種情況下,它會等待並發插入提交或成功。 由於索引上的爭用,這可以略微減少步驟2.2.2中的錯誤量。
在數據庫中的名稱列上創建唯一約束。
為name列添加唯一約束。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.