簡體   English   中英

使用Spring和Hibernate進行長時間的事務處理?

[英]Long running transactions with Spring and Hibernate?

我想要解決的基本問題是運行一個在MySQL中生成幾個臨時表的任務,這些表需要保持足夠長的時間以便在創建Java后從Java中獲取結果。 由於涉及的數據大小,任務必須分批完成。 每個批處理都是對通過JDBC調用的存儲過程的調用。 對於大型數據集,整個過程可能需要半小時或更長時間。

為了確保訪問臨時表,我在一個帶有TransactionCallbackWithoutResult的Spring事務中運行整個任務,從頭到尾完成。 否則,我可以得到一個不能訪問臨時表的不同連接(這會在我將事務包裝在事務中之前偶爾發生)。

這在我的開發環境中運行良好。 但是,在生產中我遇到以下異常:

java.sql.SQLException: Lock wait timeout exceeded; try restarting transaction

當一個不同的任務在執行長時間運行的事務期間試圖訪問某些相同的表時,就會發生這種情況。 令我困惑的是長時間運行的事務只插入或更新到臨時表中。 對非臨時表的所有訪問都是僅選擇。 從我可以找到的文檔中,默認的Spring事務隔離級別不應該導致MySQL在這種情況下阻塞。

所以我的第一個問題是,這是正確的方法嗎? 我是否可以確保在沒有長時間運行的事務的情況下通過Hibernate模板重復獲得相同的連接?

如果長時間運行的事務方法是正確的,那么我應該檢查隔離級別? 我的理解是正確的,Spring / MySQL事務中的默認隔離級別不應該鎖定只能通過選擇訪問的表嗎? 我該怎么做才能調試哪些表導致沖突,並防止這些表被事務鎖定?

我認為保持交易持續時間長。 在我的職業生涯中,“擴展”的定義從幾秒鍾下降到毫秒。

它是不可重復的問題和頭疼問題的無窮無盡的根源。

在這種情況下我會咬緊牙關並在軟件中保留一個“工作日志”,如果批次失敗,您可以反向重放以清理。

當你說你的表是臨時的時,它的事務范圍是什么? 這可能導致其他事務(可能在不同的事務上)無法查看/訪問它。 也許涉及真實表和臨時表的連接以某種方式鎖定真實表。

根本原因:您是否嘗試使用MySQL工具來確定鎖定連接的內容? 它可能類似於下一行鎖定。 我不太了解MySQL工具,但在oracle上你可以看到哪些連接阻塞了其他連接。

事務超時:您應該創建具有更長超時的第二個連接池/數據源。 將該連接池用於長時間運行的任務。 我認為您的生產環境是“試圖”通過檢測卡住的連接來幫助您。

正如Justin關於事務超時所提到的,我最近遇到了連接池(在我的案例中是Tomcat 7中的tomcat dbcp)的設置,該設置應該標記長時間運行的連接標記放棄然后關閉它們。 在調整這些參數后,我可以避免這個問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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