2012-10-04 82 views
1

我正在使用MYSQL中的表名「test」,它在事務T1期間鎖定,將在20分鐘內完成。當我在這20分鐘內通過另一個事務T2更新這個表時。我得到一個例外: -java.sql.SQLException:超出鎖定等待超時;嘗試在MYSQL中重新啓動事務異常

11:58:38,584 ERROR [STDERR] java.sql.SQLException: Lock wait timeout exceeded; try restarting transaction 
11:58:38,584 ERROR [STDERR]  at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:2928) 
11:58:38,584 ERROR [STDERR]  at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1571) 
11:58:38,584 ERROR [STDERR]  at com.mysql.jdbc.ServerPreparedStatement.serverExecute(ServerPreparedStatement.java:1124) 
11:58:38,584 ERROR [STDERR]  at com.mysql.jdbc.ServerPreparedStatement.executeInternal(ServerPreparedStatement.java:676) 

請提供給我的解決方案,我怎麼能做到這一點事務T2沒有得到這個例外?

更新mysql數據庫中的innodb_lock_wait_timeout的值是否正確,以解決此異常。我期待爲這個問題找到任何有用的解決方案。

回答

6

更新innodb_lock_wait_timeout的值是而不是解決此問題的正確方法。對於初學者來說,你聽起來像需要將它更新到20分鐘,這很荒謬。

innodb_lock_wait_timeout的默認值爲50秒 - 這是T2放棄之前等待訪問由T1鎖定的表的時間長度(並導致您所看到的異常)。

你的T2交易在做什麼?如果它只執行只讀操作(即不寫入你的表「test」),那麼你可以將數據庫的隔離級別改爲「read uncommitted」,這樣T2就可以讀取未提交的數據。但是,IMO應該避免這種黑客行爲。

相反,你應該考慮你的設計/實現。要讓事務處於打開狀態並持有20分鐘的行鎖,需要在多線程環境(例如webapp)中發生問題。

您的存檔活動(需要20分鐘)是否必須處於一個事務中?解決這個問題的一個顯而易見的方法是在每一個陳述之後提交或者將其分解爲更合理大小的交易。

+0

感謝您的回答。但是這個事務T1(在各種表上保持鎖定)將在一天內通過事件調度器執行一次歸檔目的。我希望在該事務期間對這些表執行一些其他活動。運行此事務是強制性的,所以請讓我知道有什麼方法可以解決這個問題? –

+0

事務T2正在讀寫這兩種事務。 –

+0

歸檔活動是否必須在一個事務中?解決這個問題的一個顯而易見的方法是在每一個陳述之後提交或者將其分解爲更合理大小的交易。 –

-11

重新啓動您的本地mysql以避免此類問題

+1

這工作,爲什麼-1?你知道有多少人明白接受的答案嗎?沒有... – Siddharth

+3

與其降低我的答案,爲什麼不指定你不瞭解的內容?也許還解釋爲什麼你認爲重新啓動MySql是一個有效的解決方案,在生產服務器上這個問題甚至是實用的? –

+0

@Siddharth謊言!無論如何,如果你不明白它,你不明白它,但當你這樣做時。來吧!無論如何,這篇文章指出你可以通過重新啓動來避免這個問題,儘管這是一個解決問題的臨時解決方案,並且不會再發生任何事情。如果你明白這一點,那是因爲你沒有閱讀它;) – bryn

相關問題