[英]Solve Concurrent Update/Delete Statements Java Oracle
我現在遇到的問題是同時處理SQL UPDATE
和DELETE
語句。 如果僅一個接一個地調用該程序,則沒有問題,但是,如果兩個人決定運行該程序,則可能會失敗。
我的程序做什么:
有關食物的程序,所有程序都有描述和描述的日期。 當人們輸入食物的描述時,它將被輸入數據庫,您可以在其中快速檢索描述。 如果描述是舊的7天,那么我們delete
其delete
使其過時。 但是,如果用戶使用不同的描述輸入數據庫中已有的食物,則我們將對其進行update
並更改日期。 刪除發生在更新/插入之后(將插入不需要更新的內容,然后程序檢查數據庫中是否有過時的內容並將其刪除)。
問題:
有兩個人運行該程序,一個人正試圖更新食物,另一個人則將其清除,原因是剛完成就刪除了食物。 更新不會發生,並且程序將繼續其余的更新(<-我讀這是因為我的驅動程序沒有停止。某些驅動程序在出現錯誤時停止更新)。
我想做的事:
我希望我的程序在錯誤的更新處停止或抓住那個位置,然后重新啟動進程/線程。 重新啟動將包括梳理哪些食物需要更新或插入。 因此,不良記錄將被移到插入方法而不是更新中。 更新將在中斷處繼續。 一切都很好。
我知道這不是唯一的方法,因此歡迎使用不同的方法來解決此問題。 我upsert
您可以使用upsert
語句,但這也有競爭條件。 (關於upsert
語句的問題:如果我使upsert
方法同步,它將不會有競爭條件嗎?)
謝謝
在Java代碼中將事務級別設置為可序列化。 然后,您的語句應如下所示:
update food_table set update_time = ? where ....
delete from food_table where update_time < ?
無論哪種情況,您都可能會得到可序列化的異常。 如果是更新,則需要重新插入條目。 在第二種情況下,只需忽略並再次運行即可。
根據jout jdbc連接管理,對您的問題有不同的實用解決方案。
如果該應用程序是一個客戶端服務器,並且它對每個客戶端使用專用的持久連接(即,它在程序啟動時打開jdbc連接,並在程序關閉時關閉),則可以使用select for update
語句。 在向用戶顯示記錄時,您必須發出選擇更新選項,並且當用戶執行其操作時,您將執行所需的操作並提交。 這種方法序列化了dabatabase操作,如果顯示並鎖定了多個記錄,則可能不可行 。
當您的Web應用程序帶有連接池或沒有專用連接時,可以使用第二種方法進行讀取和更新/刪除操作。 在這種情況下,您有這種情況
用戶1通過jdbc連接1選擇其數據
用戶2通過jdbc連接2選擇其數據(與用戶1相同)
用戶2使用jdbc連接3提交導致某些刪除的數據
用戶1提交數據並進行大量更新,因為該數據已通過jdbc連接2刪除
既然你不能真的在同一個JDBC連接鎖定您讀取數據,你可以發出一個select for update
更新數據前,檢查是否有數據。 如果您有數據,則可以對其進行更新(並且由於相同數據上的每個刪除命令都在等待您選擇更新終止,因此其他會話將不會刪除它們); 如果您沒有數據,因為它們在用戶顯示期間已被刪除,則必須重新插入它們。 您的delete語句在date列上必須具有表示最后更新的過濾器。
您可以使用其他方法,並避免使用例如
update food-table set last_update=? where id=? and last_update=<the last update you have in java program>
並且必須檢查update語句是否確實更新了一行(在jdbc中,executeUpdate返回已修改的行數,但是如果使用的是“純” JDBC或某種框架,則沒有指定),並且它沒有更新任何行您必須發出插入語句。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.