[英]Handling concurrent transaction in Spring-Boot
因此,這似乎是一個非常菜鳥的問題,但是經過一番谷歌搜索后,我找不到最佳方法。
問題:有一個Spring-Boot應用程序,可以與數據庫(MySQL)交互。 考慮一個表T1,我不想為每個用戶只有一個有效條目。 因此,如果出現下一個條目,它將軟刪除(通過設置Deleted-at列)該用戶的現有行並創建一個新條目。 現在問題來了,幾乎同時存在多個請求。
我的事務塊,看起來像這樣:
@Transactional
someMethod() {
CheckIfAnyValidEntryForUser(U1);
SoftDeleteExistingEntries(U1);
DoComputation(); // Takes around a second.
InsertNewRow();
}
現在,如果短時間內有多個請求,那么我的代碼最終將為單個用戶插入多個有效條目。
由於我要編輯的行可能以前不存在,因此無法按版本號進行樂觀鎖定。
本來想在此someMethod上獲取Global-Lock,但是這使我的等待時間增加了太多。
另一種方法可能是在數據庫中為列(包括Deleted-at列)使用復合唯一鍵。 然后處理代碼中的提交失敗。
這似乎是一個非常普遍的問題,那么通常如何處理? 最好的方法是什么?
您可以使用@Transactional
批注的isolation
屬性,並將此屬性設置為Isolation.SERIALIZABLE
:
@Transactional(isolation= Isolation.SERIALIZABLE)
注意 :
Spring默認使用DEFAULT隔離策略,該策略使用基礎數據存儲的默認隔離級別。 使用SERIALIZABLE隔離使您的事務在讀取,寫入,范圍鎖定時執行; 因此它們看起來好像是以序列化的方式執行的,從而防止了臟讀,不可重復讀和幻像讀。
也
專為與Propagation.REQUIRED或Propagation.REQUIRES_NEW一起使用而設計,因為它僅適用於新啟動的交易。 如果希望在參與具有不同隔離級別的現有事務時拒絕隔離級別聲明,請考慮在事務管理器上將“ validateExistingTransactions”標志切換為“ true”。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.