簡體   English   中英

在Spring-Boot中處理並發事務

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

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