我正在尝试测试第一个事务,如果它是SUCCESS,那么我尝试第二个,如果第二个也是SUCCESS然后我提交两个,如果第二个是失败,我需要回滚第一
所以我有以下函数返回一个可以是其中一个状态的字典:
0(意味着交易失败但设法回滚) - > sql transaction
1(意味着交易成功) - > sql transaction
-1(意味着交易失败并且没有设法回滚) - > sql transaction
Public Function execDBTrans_valMod(transactionName As String, ByVal emailSubject As String, ByVal emailBody As String, ByVal queryString As String, Optional ByVal connectionString As String = "SQLConnectionHere") As Dictionary(Of Integer, SqlTransaction)
Dim trans_dict As New Dictionary(Of Integer, SqlTransaction)
Using connection As New SqlConnection(ConfigurationManager.ConnectionStrings(connectionString).ToString) 'LATEST EXEC
connection.Open()
Dim command As New SqlCommand(queryString, connection)
Dim transaction As SqlTransaction = connection.BeginTransaction(transactionName)
command.Transaction = transaction
Try
command.CommandTimeout = 3600 'Used for large updates
command.ExecuteNonQuery()
'transaction.Commit() DO NOT COMMIT so that we can commit only after we verify that pbSite can be inserted
trans_dict.Add(1, transaction)
Return trans_dict
Catch dbTrans_ex As Exception
Try
transaction.Rollback()
trans_dict.Add(0, transaction)
Return trans_dict
Catch dbTrans2_ex As Exception
trans_dict.Add(-1, transaction)
Return trans_dict
' This catch block will handle any errors that may have occurred on the server that would cause the rollback to fail, such as a closed connection.
End Try
End Try
End Using
End Function
然后我在函数中有以下代码:
Dim transPB_dict = execDBTrans_valMod("transPB", failSubject, failBody, buildInsert)
If transPB_dict.ContainsKey(1) Then 'SUCCESS
Dim transPBsite_dict = execDBTrans_valMod("transPBsite", failSubject, failBody, buildInsert_PBsite)
If transPBsite_dict.ContainsKey(1) Then
transPB_dict.Item(1).Commit()
transPBsite_dict.Item(1).Commit()
Return True
Else 'Failed to create the tables for this user so rollback all the tables that were created in the previous transaction (all the old tables in panelbase)
transPB_dict.Item(1).Rollback() 'THIS THROWS THE ERROR This SqlTransaction has completed; it is no longer usable
Return False
End If
Else
Return False
End if
我还没有提交第一个事务,为什么说当我尝试回滚时sqlTransaction已经完成了??
感谢您的帮助!
答案 0 :(得分:0)
退出USING块时
Using connection As New SqlConnection...
End Using
您的连接已关闭并处理,并且已提交针对该连接的所有待处理事务。您不能对多个连接进行相同的交易。
仅创建并打开一次连接。将此连接(和事务)传递给将要处理SQL的方法。然后,当它完成后,您可以提交您的交易并关闭/处置您的连接。
处理多个SQL命令之间的单个连接将提高程序的速度,因为每个连接都会产生开销,这会降低您的速度。
答案 1 :(得分:0)
因为您的联系是在execDBTrans_valMod
中打开和关闭的
当连接关闭时,与连接关联的事务结束。
如果您需要在第二个命令失败时回滚第一个命令,则只需要一个事务 连接和事务应由命令执行程序的调用者管理。
您需要以下内容:
Public Sub execDBTrans_valMod(ByVal transaction As SqlTransaction, ByVal emailSubject As String, ByVal emailBody As String, ByVal queryString As String)
Using command As New SqlCommand(queryString, transaction.Connection, transaction)
Try
command.CommandTimeout = 3600 'Used for large updates
command.ExecuteNonQuery()
Catch ex As Exception
' Do something with emailSubject and emailBody??
' Then rethrow ex to be caught by the caller.
Throw
End Try
End Using
End Sub
来电者:
Using connection As New SqlConnection(ConfigurationManager.ConnectionStrings("SQLConnectionHere").ToString)
connection.Open()
Using transaction As SqlTransaction = connection.BeginTransaction()
Try
execDBTrans_valMod(transaction, failSubject, failBody, buildInsert)
execDBTrans_valMod(transaction, failSubject, failBody, buildInsert_PBsite)
transaction.Commit()
Return True
Catch ex As Exception
Try
transaction.Rollback()
Catch exRollback As Exception
' Do logging or something when rollback failed.
End Try
Return False
End Try
End Using
End Using