我有一個多線程客戶端/服務器系統,客戶端連續不斷地向存儲在特定表中的服務器發送數據,但這些數據只是重要的幾天之後,所以在超過使用期限後將被刪除。
服務器是用J2SE編寫的,數據庫是MySQL,我的表使用InnoDB引擎。它包含數百萬條目(並且爲了使用而被正確索引)。
一個計劃線程每天運行一次刪除舊條目。此線程可能需要大量時間進行刪除,因爲由於不同的原因,要刪除的行數可能非常大(幾百萬行)。
在我的特定系統上刪除250萬行需要大約3分鐘。
的插入線(和讀取線程)得到一個超時錯誤,告訴我如何防止MySQL InnoDB通過JDBC爲刪除語句設置鎖定
Lock wait timeout exceeded; try restarting transaction
1)好了,有一件事是,我怎麼能簡單地從我的Java代碼的狀態?我寧願自己處理這種情況,而不是等待。但更重要的是,如何防止這種情況?
2)我能用
conn.setIsolationLevel(Connection.TRANSACTION_READ_UNCOMMITTED)
爲讀線程,因此無論他們將獲得他們的信息,如果它是目前最準確的(這是絕對OK這個用例)?
3.)我能做些什麼來插入線程以防止阻塞?他們純粹插入數據到表中(主鍵是元組userid,servertimemillis)。
4.)我是否應該更改我的刪除線程 - 它純粹刪除元組userid的數據,大於specialtimestamp。
編輯:
當讀MySQL documentation here,我不知道如果我不能簡單地定義與
conn.setIsolationLevel(Connection.TRANSACTION_READ_COMMITTED)
插入和刪除行的連接,實現我需要什麼。它表示UPDATE和DELETE語句使用唯一索引和唯一搜索模式只會鎖定匹配索引條目,但不會鎖定之前的差距,因此行仍可以插入到該差距中。因爲我不能簡單地在生產環境中嘗試它,所以在這方面獲得您的經驗將是非常好的 - 並且在測試環境中模擬它是一項巨大的努力。
是的,那會比現在做得更好,我可以確定我不會鎖定其他線程太長。我將這一點考慮在內以作爲快速的解決方法,但正如您已經注意到的那樣,如果在下一個回合之前刪除的行數太大而無法在'x * n'時間段內刪除,那麼它可能會變得棘手開始...我的想法與'conn.setIsolationLevel(Connection.TRANSACTION_READ_COMMITTED)''怎麼樣? – Schlangi
我試過在備份數據庫上,它的工作速度比單個刪除語句快得多。但它具有與鎖定相同的固有問題,即使這是因爲短時間的原因。 – Schlangi
我將您的解決方案標記爲已接受,但我仍然在考慮對隔離級別的更改... – Schlangi