簡體   English   中英

解決並發更新/刪除語句Java Oracle

[英]Solve Concurrent Update/Delete Statements Java Oracle

我現在遇到的問題是同時處理SQL UPDATEDELETE語句。 如果僅一個接一個地調用該程序,則沒有問題,但是,如果兩個人決定運行該程序,則可能會失敗。

我的程序做什么:

有關食物的程序,所有程序都有描述和描述的日期。 當人們輸入食物的描述時,它將被輸入數據庫,您可以在其中快速檢索描述。 如果描述是舊的7天,那么我們deletedelete使其過時。 但是,如果用戶使用不同的描述輸入數據庫中已有的食物,則我們將對其進行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.

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