2012-09-14 37 views
0

我們正在嘗試實施一個修補客戶端軟件的程序 - 最初將運行一個.SQL,但如果腳本在任何時候都失敗,我們將回滾數據庫並停止客戶端DLL導入過程從工作。通過多個數據庫上的事務執行SQL腳本

我們的SQL腳本具有「GO」語句,因此我們無法將使用sp_executesql的漂亮存儲過程放在一起,因爲這不允許「GO」 - 相反,如果我們有一個如下所示的SQL腳本:

USE [SomeDatabase] 

BEGIN TRANSACTION 
GO 
IF (OBJECT_ID(N'[dbo].[ProcedureToUpdate]') IS NOT NULL) 
    DROP PROCEDURE [dbo].[ProcedureToUpdate] 
GO 
IF @@ERROR <> 0 
    AND @@TRANCOUNT > 0 
    ROLLBACK TRAN 
GO 
IF @@TRANCOUNT = 0 
    BEGIN 
     --Flag that the procedure hasn't been dropped, begin another transaction 
     BEGIN TRANSACTION 
    END 
GO 

PRINT 'Creating procedure' 
GO 

CREATE PROCEDURE [dbo].[ProcedureToUpdate] 
AS 
    SELECT * 
    FROM [dbo].[SomeTable] st 
      INNER JOIN [dbo].[AnotherTable] at ON st.PK = at.fk 

GO 

IF @@ERROR <> 0 
    AND @@TRANCOUNT > 0 
    ROLLBACK TRAN 
GO 
IF @@TRANCOUNT = 0 
    BEGIN 
     --Flag that the procedure hasn't been created, begin another transaction 
     BEGIN TRANSACTION 
    END 
GO 

然後,我們正在執行在.NET中有問題的數據庫事務中的每個「動作」(由go語句拆分) - 如果循環內部出現任何故障,這將回滾數據庫。

Using con As New SqlConnection(ConnectionString) 
    con.Open() 
    Dim cmd As SqlCommand = con.CreateCommand() 
    Dim transaction As SqlTransaction = con.BeginTransaction("Upgrade") 
    cmd.Connection = con 
    cmd.Transaction = transaction 
    Try 
     For Each transactionalScript In transactionalScripts 
     cmd.CommandText = transactionalScript 
     Dim result = cmd.ExecuteNonQuery() 
     Next 
     transaction.Commit() 
    Catch ex As Exception 
     Log(String.Format("{0} : Script Failed", DateTime.Now.ToString())) 
     Log(String.Format("{0} : Reason: {1}", DateTime.Now.ToString(), ex.Message)) 
     transaction.Rollback("Upgrade") 
     Log(String.Format("{0} : Database rolled back", DateTime.Now.ToString())) 
    End Try 
    End Using 

最後 - 這是我的問題。我們需要處理多達4個.SQL腳本,每個腳本將用於單個服務器上的不同數據庫。如果4個腳本中的任何一個發生故障,我們應該回滾腳本受到影響的每個數據庫 - 有什麼建議嗎?

回答

0

看看使用TransactionScope

如果您在TransactionScope內使用多個連接,則會發布分佈式事務。這有它自己的要求(如DTC),但這當然是你想要開始尋找的地方。

相關問題