一个事务中的两个函数查询

时间:2016-05-19 17:41:44

标签: sql-server vb.net

有两个功能,用于多次使用的应用程序。目前有目的是在一次交易中将它们用作一个,但我不确定我是否可以将它们放在下面的方式中。请看下面的内容:

第一个:

 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

3 个答案:

答案 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