2012-02-01 143 views
0

我使用線程,當我提交數據時,我得到觸發死鎖。如何防止數據庫死鎖?觸發檢查是否存在行,如果存在,那麼就回滾..數據庫死鎖時觸發觸發器

我讀這一點,但它是沒有幫助的太多:

http://www.sql-server-performance.com/2006/deadlocks/

http://blog.sqlauthority.com/2007/05/16/sql-server-fix-error-1205-transaction-process-id-was-deadlocked-on-resources-with-another-process-and-has-been-chosen-as-the-deadlock-victim-rerun-the-transaction/

如何避免這個錯誤?

代碼:

advertismentsDao.Save(ad); 
advertismentsDao.CommitChanges(); 

,並承諾火災這觸發

ALTER TRIGGER [dbo].[TRG_ViolateAdvertisements] ON [dbo].[Advertisements] 
AFTER INSERT, UPDATE 
AS 
BEGIN 
    IF EXISTS (SELECT 1 FROM INSERTED ins JOIN dbo.Advertisements ad 
        ON ISNULL(ins.Price, 0) = ISNULL(ad.Price, 0) 
        AND ISNULL(ins.HollidayDuration, 0) = ISNULL(ad.HollidayDuration, 0) 
        AND ISNULL(ins.Name, 0) = ISNULL(ad.Name, 0) 
        AND ISNULL(ins.Description, 0) = ISNULL(ad.Description, 0) 
        AND ISNULL(ins.Cities_idCities, 0) = ISNULL(ad.Cities_idCities, 0) 
        AND ISNULL(ins.Areas_idAreas, 0) = ISNULL(ad.Areas_idAreas, 0) 
        AND ISNULL(ins.Countries_idCountries, 0) = ISNULL(ad.Countries_idCountries, 0) 
        AND ins.Agencies_idAgencies = ad.Agencies_idAgencies 
        --AND ins.Url = ad.Url 
        HAVING COUNT(1) > 1) 
    BEGIN 
     RAISERROR ('Unique constraint violation in dbo.Advertisements', 16, 1) 
     ROLLBACK TRAN; 
    END 
END 

,但我得到的錯誤:

Transaction (Process ID 78) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction.
StackTrace:
at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection)
at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection)
at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning()
at System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj)
at System.Data.SqlClient.SqlDataReader.ConsumeMetaData()
at System.Data.SqlClient.SqlDataReader.get_MetaData()
at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString)
at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async)
at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result)
at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method)
at System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method)
at System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior behavior)
at System.Data.Common.DbCommand.System.Data.IDbCommand.ExecuteReader()
at NHibernate.AdoNet.AbstractBatcher.ExecuteReader(IDbCommand cmd)
at NHibernate.Id.IdentityGenerator.InsertSelectDelegate.ExecuteAndExtract(IDbCommand insert, ISessionImplementor session)
at NHibernate.Id.Insert.AbstractReturningDelegate.PerformInsert(SqlCommandInfo insertSQL, ISessionImplementor session, IBinder binder)

+0

任何想法如何防止死鎖? – senzacionale 2012-02-01 12:04:42

+0

有大量關於分析和防止死鎖的信息,包括SQL Server文檔中的信息:http://msdn.microsoft.com/en-us/library/ms188246.aspx http://msdn.microsoft。 com/en-us/library/ms191242.aspx你的問題到底是什麼?你只是說你發現的信息沒有幫助,但你沒有解釋爲什麼。 – Pondlife 2012-02-01 12:09:51

+1

你爲什麼試圖通過觸發器而不是唯一的約束來強制執行一個唯一的約束? – 2012-02-01 12:28:34

回答

1

使用唯一約束代替。

例如:

Alter Table Advertisements 
ADD Constraint Advertisements_UQ1 Unique (
    Price, 
    HollidayDestination, 
    Name, 
    Description, 
    Cities_idCities, 
    Areas_idAreas, 
    Countries_idCountries, 
    Agencies_idAgencies 
) 
+0

好主意Ben,thx – senzacionale 2012-02-02 06:09:05