我在網絡上的數據庫上執行插入操作,並且我想確保我永遠不會嘗試插入已插入的數據。客戶端運行在Web瀏覽器中,使用Javascript將XMLHttpRequest發送到包含要插入數據的服務器。如果出現錯誤,我必須稍後再試 - 例如,可能存在暫時的網絡錯誤。但是,我不知道我可以保證我會通知插入成功,因爲在請求傳遞到服務器之後但在可以返回成功答覆之前,網絡可能會關閉。雖然這看起來對我來說不太可能,但是如果發生這種情況,將會完全搞亂數據庫,因爲無法知道某些條目不應該在那裏。如何確保我不會執行兩次相同的數據庫事務?
1
A
回答
1
使用是否存在要插入的數據,以便如果第二個相同的事務處理完畢,則簡單地忽略它。喜歡的東西:
INSERT MyTable (Value1, Value2, Value3)
SELECT @Value1, @Value2, @Value3
WHERE
NOT EXISTS (
SELECT *
FROM dbo.MyTable T
WHERE
T.Value1 = @Value1
AND T.Value2 = @Value2
)
;
請注意,這並不能完全解決潛在的競爭條件,其中兩個客戶端試圖執行在同一時間同一行動 - EXISTS
子句中的時間執行INSERT
操作之前,這可能會產生兩個試圖插入的客戶端。因此,您必須添加諸如WITH (UPDLOCK, HOLDLOCK)
之類的鎖定(對於併發性非常糟糕,因爲如果該行不存在,它必須採取範圍鎖定來阻止無關的數據插入操作),或者在客戶機中適當地容忍有關重複鍵的錯誤。
如果它實際上是沒關係對於要,只要客戶端發送它複製的數據,那麼你就可以適應在幾個方面:
表中添加附加列,直到它是獨特的。
或者,創建作爲事務一部分的時間戳/序列號,插入後(在數據庫事務中)將此序列號記錄到表中。將插入與缺少此序列號相關聯。
開發一些策略,爲您的客戶持有發送請求,直到它們可以ACKED可能是一個附加的保護層,它同時可能會阻止一些重複的嘗試擺在首位 - 如果你沒有得到的現在確認,但稍後到達時,您確認/刪除排隊的已發送事務。
爲了將其推廣到防止重複DELETE
和UPDATE
,您應該添加一個column of type rowversion。將此值包含在所有查詢的WHERE
子句中,如果有人自上次讀取該行後觸摸了該行,那麼這些查詢將不會影響行。您仍然必須檢測到沒有行受到影響,之後才能做出明智的做法 - 這可能非常困難 - 但至少您已經檢測到並避免了編輯衝突或重複操作。
如果問題不能隔離到特定行的特定編輯,那麼請提出一個新問題,提供一些具體示例,以便您可以獲得更好的建議。給我一個帶有新問題鏈接的評論,我會看看。
0
嘗試添加一些約束你的領域:
ALTER TABLE Persons ADD CONSTRAINT MyTable UNIQUE (Value1, Value2, Value3)
相關問題
- 1. 如何確保代碼不會在兩次之間執行?
- 2. 如何確保相同的元素不會在數組中出現兩次
- 3. 如何確保數據庫事務只發生一次?
- 4. 我如何確保行不會用EF/LINQ加載兩次
- 5. 確保相同的列表輸出不會出現兩次
- 6. 如何確保任務同時執行?
- 7. 如何確保同一份工作不會同時運行兩次?
- 8. 如何確保不會啓動服務兩次android
- 9. 我的websql事務將不會執行
- 10. 相同的查詢,不同的數據庫,相同的數據庫結構,相同的數據庫服務器,不同的執行計劃
- 11. 如何確保SQLite從不創建具有相同ID的行兩次?
- 12. GDB執行相同的語句兩次
- 13. 我如何確保相同的值不被插入到數據庫中?
- 14. 如何確保兩行不具有相同的值
- 15. HSQL數據庫偶爾會執行兩次schema.sql
- 16. 相同的查詢,相同的數據庫,不同的執行計劃和執行的時間顯着不同
- 17. Python - 猜謎遊戲確保用戶不會輸入兩次相同的字母
- 18. 如何確保所選日期在數據庫中相同?
- 19. 確保相同的配置用於庫和可執行文件
- 20. 的循環將不會執行兩次
- 21. 確保不會多次下載相同的javascript文件
- 22. 如何防止Recycler視圖項執行兩次相同的任務
- 23. 如何在同一個Hibernate事務中保存兩個數據庫記錄?
- 24. 如何同步不同服務器的兩個數據庫?
- 25. 如何爲不同的事件執行相同的代碼
- 26. Django如何確定我的數據庫是否支持事務?
- 27. 軟件事務內存是否與數據庫事務相同?
- 28. 如何確保不同NoSQL數據表的更新操作的原子事務?
- 29. 用不同的服務器/數據庫執行SQL任務
- 30. 故事板不能執行兩次
您正在使用什麼數據庫管理系統? (PostgreSQL,MySQL,MS-SQL,Oracle,...?)而且 - 你是否熟悉主鍵,獨特的約束等? – ruakh
你需要在db中做到這一點,而不是在網絡上 – dandavis
是的,但是如何?插入的行基本上是一個字符串命令的日誌,並不要求它們是唯一的,唯一的要求是它們沒有被錯誤地複製(因爲否則當重播日誌時它將導致錯誤的結束狀態)。 – Michael