在我的SQL表(2008)中,我有一個名爲Timestamp的時間戳列。EF併發導致觸發問題
在我的.NET項目,我有一個POCO類的屬性
public byte[] Timestamp {get; set;}
在我的配置代碼,我有以下幾點:
Property(p => p.Timestamp).IsRowVersion();
現在,如果我打開兩個編輯畫面對其中一個進行更改並保存(保存被接受),然後在第二個中進行更改並保存(保存被DbUpdateConcurrencyException拒絕)。
有一件我覺得奇怪的事情是,即使當我收到併發異常時,SQL事件探查器也會顯示發送到SQL數據庫的更新請求。更新不會在數據庫上提交,但會被髮送。這是正常的嗎?我有預期的EF提前檢查,甚至不發送請求。
最後,如果我能夠在這個表中的觸發器:
ALTER TRIGGER [dbo].[trg_person_log_changes]
ON [dbo].[Person]
AFTER INSERT,DELETE,UPDATE
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
DECLARE @auditBody XML
DECLARE @actionType char(1)
DECLARE @username nvarchar(100)
if not exists(select * from deleted)
Begin
SET @actionType = 'I'
SET @username = (select Case
When lastchangedby is null or lastchangedby = '' then Suser_name()
Else lastchangedby
End
from inserted)
End
else if not exists(select * from inserted)
Begin
SET @actionType = 'D'
SET @username = Suser_name()
End
else
Begin
SET @actionType = 'U'
SET @username = (select distinct Case
When lastchangedby is null or lastchangedby = '' then Suser_name()
Else lastchangedby
End
from inserted)
End
If @actionType = 'I'
Set @auditBody = (select 'Person' as "@tableName", 'True' as "@synch",
(select * from inserted for xml path('DataItem'), type, binary base64)
for xml path('Root'))
Else
SET @auditBody = (select 'Person' as "@tableName", 'True' as "@synch",
(select * from deleted for xml path('DataItem'), type, binary base64)
for xml path('Root'))
insert into [dbo].[AuditLog]
([Action]
,[ActionDate]
,[ActionUser]
,[AuditData]
)
values (
@actionType
,getdate()
,@username
,@auditBody)
END
現在,當我嘗試保存第二個編輯,我不再得到DbUpdateConcurrencyException,我得到一個錯誤,指出ActionUser不能空值。再一次,我認爲我的觸發器正在執行,因爲即使存在衝突,EF也允許更新通過。
關於我可能做錯什麼想法?
注意
這是一個MVC項目。在我的編輯POST控制器中,我收到一個DTO對象,其中包含所有表單屬性(其中之一是Timestamp - 我的編輯表單上的隱藏字段)。我正在從datacontext加載編輯後的人員,並將編輯後的DTO對象的屬性映射到從datacontext返回的Domain對象中。
謝謝你。我的一個朋友(謝謝傑克)給了我一個解決方案。他告訴我在我的觸發器中檢查@@ ROWCOUNT = 0。如果這是真的,那麼我只是回來,並沒有做任何添加到審計日誌的邏輯。 – RHarris 2013-04-10 20:26:20
好的,可以節省一些性能,但是日誌的添加應該回滾以及達到目的。 – 2013-04-10 20:28:01
對不起,應該更清楚了。沒有添加到日誌回滾。由於更新沒有更新任何行(由於where子句),因此觸發器中的@@ ROWCOUNT爲0 ...因此,我退出觸發器並且不向審計日誌添加任何內容......沒有任何事情可以回滾! – RHarris 2013-04-10 21:10:16