Have two functions which are used for application purposes where they are consume many times. Currently there is purpose to use them as one within one transaction but i am not sure if i can put them in the way as below. Take look below on them:
First one:
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
Second one:
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
Both to transaction:
Now i would like to make function with transaction and use above functions as one. The problem is both first and second function already open their own connection, and here has to be only one if am not mistaken. This is what i don't know how to do.
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
You could add an optional parameter that is passed only when the method is called from the transactional code. This parameter is the connection opened before calling the two methods. In this scenario you need to remove the using around the connection and dispose it only if the call comes from non transactional code.
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
Of course the transactional code could now supply its connection to the Delete method while the other parts of your code ignore it.
Call New DALVariation_Attribute().DeleteAllWhereVarId(varId, connection)
Delete(varId, connection)
transaction.Commit()
You could also look at the TransactionScope class that could allow you to leave your code as it is now
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
However please read also TransactionScope automatically escalating to MSDTC on some machines?
I have never tried this but I have read that TransactionScope will work over multiple connections. Check out this article: https://msdn.microsoft.com/en-us/library/ee818746(v=vs.110).aspx
Edit: No TransactionScope is different. There is a really good example in the link that actually works over two connections so it should get you well on your way.
You can create overloads for your functions to accept a transaction. Something like:
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
and
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
so from the caller routine you can do something like:
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
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.