有两个功能,用于多次使用的应用程序。目前有目的是在一次交易中将它们用作一个,但我不确定我是否可以将它们放在下面的方式中。请看下面的内容:
第一个:
Public Function Delete(varId As Integer) As Boolean
Dim result As Boolean = False
Using con As New SqlConnection(strcon)
Using cmd As New SqlCommand("DELETE FROM T_Variation WHERE Id=@Id", con)
cmd.CommandType = CommandType.Text
cmd.Parameters.AddWithValue("@Id", varId)
con.Open()
Dim rowsAffected As Integer = cmd.ExecuteNonQuery()
con.Close()
result = True
End Using
End Using
Return result
End Function
第二个:
Public Function DeleteAllWhereVarId(pVarId As Integer) As Boolean
Dim result As Boolean = False
Using con As New SqlConnection(strcon)
Using cmd As New SqlCommand("DELETE FROM T_Variation_Attribute WHERE FK_Variation_ID=@FK_Variation_ID", con)
cmd.CommandType = CommandType.Text
cmd.Parameters.AddWithValue("@FK_Variation_ID", pVarId)
con.Open()
Dim rowsAffected As Integer = cmd.ExecuteNonQuery()
con.Close()
result = True
End Using
End Using
Return result
End Function
两者都要交易:
现在我想用事务创建函数并将上述函数用作一个函数。问题是第一个和第二个功能已经打开了它们自己的连接,如果没有弄错,这里必须只有一个。这是我不知道该怎么做。
Public Function DeleteWithAttributes(varId As Integer) As Boolean
Dim result as Boolean = true
Using connection As New SqlConnection(strcon)
'-- Open generall connection for all the queries
connection.Open()
'-- Make the transaction.
Dim transaction As SqlTransaction
transaction = connection.BeginTransaction(IsolationLevel.ReadCommitted)
Try
Call New DALVariation_Attribute().DeleteAllWhereVarId(varId)
Delete(varId)
transaction.Commit()
Catch ex As Exception
result = False
'-- Roll the transaction back.
transaction.Rollback()
End Try
End Using
Return result
End Function
答案 0 :(得分:0)
您可以添加仅在从事务代码调用方法时传递的可选参数。此参数是在调用这两个方法之前打开的连接。在这种情况下,您需要删除连接周围的使用,并仅在呼叫来自非事务性代码时处置它。
Public Function Delete(varId As Integer, Optional externalCon as SqlConnection = Nothing) As Boolean
Dim result As Boolean = False
Dim localCon as SqlConnection
Try
' if there is no external connection then create one locally
if externalCon Is Nothing Then
localCon = new SqlConnection(strcon)
localCon.Open()
else
' use the external passed connection
localCon = externalCon
End if
Using cmd As New SqlCommand("DELETE FROM T_Variation WHERE Id=@Id", localCon)
cmd.Parameters.AddWithValue("@Id", varId)
Dim rowsAffected As Integer = cmd.ExecuteNonQuery()
result = True
End Using
Finally
' if we have created the connection dispose/close it
if externalCon Is Nothing Then
localCon.Dispose()
End if
End Try
Return result
End Function
当然,事务代码现在可以提供与Delete方法的连接,而代码的其他部分则忽略它。
Call New DALVariation_Attribute().DeleteAllWhereVarId(varId, connection)
Delete(varId, connection)
transaction.Commit()
您还可以查看TransactionScope类,它可以让您保留现在的代码
Public Function DeleteWithAttributes(varId As Integer) As Boolean
Dim result as Boolean = true
Using scope As New TransactionScope()
Using connection As New SqlConnection(strcon)
connection.Open()
Try
Call New DALVariation_Attribute().DeleteAllWhereVarId(varId)
Delete(varId)
scope.Complete()
Catch ex As Exception
result = False
End Try
End Using
' if you reach this using without calling scope.Complete
'the transaction is automatically aborted
End Using
Return result
End Function
但请同时阅读TransactionScope automatically escalating to MSDTC on some machines?
答案 1 :(得分:0)
我从未尝试过这个,但我已经读过TransactionScope将在多个连接上工作。看看这篇文章: https://msdn.microsoft.com/en-us/library/ee818746(v=vs.110).aspx
编辑: 没有TransactionScope是不同的。链接中有一个非常好的例子,它实际上可以在两个连接上运行,因此它可以帮助你顺利完成。
答案 2 :(得分:0)
您可以为函数创建重载以接受事务。类似的东西:
Public Function Delete(tran As SqlTransaction, varId As Integer) As Boolean
Dim result As Boolean = True
If tran Is Nothing Then
Using con As New SqlConnection(strcon)
Using cmd As New SqlCommand("DELETE FROM T_Variation WHERE Id=@Id", con)
cmd.CommandType = CommandType.Text
cmd.Parameters.AddWithValue("@Id", varId)
Try
con.Open()
Dim rowsAffected As Integer = cmd.ExecuteNonQuery()
Catch
result = False
End Try
End Using
End Using
Else
Using cmd As New SqlCommand("DELETE FROM T_Variation WHERE Id=@Id", tran.Connection)
cmd.Transaction = tran
cmd.CommandType = CommandType.Text
cmd.Parameters.AddWithValue("@Id", varId)
Try
Dim rowsAffected As Integer = cmd.ExecuteNonQuery()
Catch
result = False
End Try
End Using
End If
Return result
End Function
Public Function Delete(varId As Integer) As Boolean
Return Delete(Nothing, varId)
End Function
和
Public Function DeleteAllWhereVarId(tran As SqlTransaction, pVarId As Integer) As Boolean
Dim result As Boolean = True
If tran Is Nothing Then
Using con As New SqlConnection(strcon)
Using cmd As New SqlCommand("DELETE FROM T_Variation_Attribute WHERE FK_Variation_ID=@FK_Variation_ID", con)
cmd.CommandType = CommandType.Text
cmd.Parameters.AddWithValue("@FK_Variation_ID", pVarId)
Try
con.Open()
Dim rowsAffected As Integer = cmd.ExecuteNonQuery()
Catch
result = False
End Try
End Using
End Using
Else
Using cmd As New SqlCommand("DELETE FROM T_Variation_Attribute WHERE FK_Variation_ID=@FK_Variation_ID", tran.Connection)
cmd.Transaction = tran
cmd.CommandType = CommandType.Text
cmd.Parameters.AddWithValue("@FK_Variation_ID", pVarId)
Try
Dim rowsAffected As Integer = cmd.ExecuteNonQuery()
Catch
result = False
End Try
End Using
End If
Return result
End Function
Public Function DeleteAllWhereVarId(pVarId As Integer) As Boolean
Return DeleteAllWhereVarId(Nothing, pVarId)
End Function
所以从调用例程开始,您可以执行以下操作:
Public Sub DoSomeWOrk()
Using con As New SqlConnection(strcon)
Dim commit As Boolean = True
con.Open()
Dim tran As SqlTransaction = con.BeginTransaction
If commit Then commit = commit And Delete(tran, 1)
If commit Then commit = commit And DeleteAllWhereVarId(tran, 1)
If commit Then
tran.Commit()
Else
tran.Rollback()
End If
End Using
End Sub