I 認爲我遇到的問題是併發問題,但我想我不太瞭解SQL Server事務,以確定要做什麼。外鍵約束衝突併發問題
我有插入新行到一個表中的存儲過程,然後使用由INSERT
創建的ID創建另一個表中的記錄,這對RID一個外鍵約束:
INSERT INTO tbl_Registrations ...
DECLARE @RID int;
--get newly-created registration ID
SET @RID=(SELECT MAX(RID) FROM tbl_Registrations WHERE ...);
INSERT INTO tbl_RegistrationCertificates VALUES (@RID, 9);
這個存儲過程是從網站上的用戶交互中調用的,每次我測試它時,它都可以正常工作。然而,每過一段時間,我會從我們的錯誤處理一封電子郵件,但以下情況除外:
System.Data.SqlClient.SqlException (0x80131904): The INSERT statement conflicted with the FOREIGN KEY constraint "FK_tbl_RegistrationCertificates_tbl_Registrations".
The conflict occurred in ... table "dbo.tbl_Registrations", column 'RID'.
The statement has been terminated.
但是,無論是我的用戶在點擊「更新」按鈕,持續,直到他們看到變化,或者即使消息顯示The statement has been terminated
,交易仍在進行,因爲使用來自電子郵件的其他信息,我可以看到這兩個表已實際更新。
我知道我不給一噸的信息在這裏,但我無法找到答案的大問題是:
- 是否在聲明的末尾分號T中做任何事 - SQL?我只注意到在INSERT語句結尾處沒有分號。 (我通常會讓他們擺脫習慣,但我正在開發其他人制造的系統。)
- 這對於瞭解SQL Server的人比我更瞭解的人是否看起來像是一個併發問題?
- 如果看起來像是一個併發問題,我可以使用事務來減輕它,我該怎麼做?
編輯:我只是意識到SP是不是什麼都拋出了錯誤。網站還有另一個地方做插入,而不檢查是否存在RID。不過,我很高興我提出了這些問題,因爲我仍然不知道其他答案。
啊'SCOPE_IDENTITY()'是不是我以前見過;這非常有幫助。顯然,爲了簡潔起見,我留下了很多代碼,但是如果基於SP的參數滿足其他條件,則只會執行第二個「INSERT」。在這種情況下交易是否有意義? –
還有一個問題:使用事務和批分隔符有什麼區別? 'GO'與'BEGIN TRANSACTION ... COMMIT TRANSACTION'? –
事務邏輯上將多個語句分組在一起,以使它們成功或失敗。在我上面的代碼中,如果由於某種原因'INSERT' to _tbl_RegistrationCertificates_失敗,那麼'INSERT' to _tbl_Registrations_也會回滾。當一組報表全部被視爲一個操作(BEGIN'和'COMMIT'之間的所有內容)時,事務可幫助您保持邏輯上一致的狀態。另一方面,「GO」只是告訴SQL Server工具運行一組語句。 –