SqlTransaction已经完成,它不再可用,回滚问题

时间:2017-03-01 04:17:54

标签: asp.net sql-server vb.net try-catch sqlexception

我偶尔会遇到此错误消息:

  

SqlTransaction已完成;它不再可用了。

我不确定是什么导致弹出这个错误,我尝试将SQL Timeout设置为无穷大。

是不是因为我的代码结构?

这不是小组用户时发生的,而是在庞大的用户组时频繁发生。

Public Function PostCustomerSet(ByVal ds As CustomerHeaderDetailDataSet, ByVal Table As String, ByRef SessionKeys As String, ByRef errMsg As String, ByVal SubmitType As Integer, ByVal callWrapper As Boolean) As String
    errMsg = Nothing
    Dim newkey As PrimaryKey
    Dim oldkey As PrimaryKey
    Try
        transaction = EnterpriseUtils.StartTransaction(Connection1, m_Dict)
        If ds.CustomerHeader.Rows.Count > 0 Then
            Dim SessionKey As PrimaryKey = PrimaryKey.FromString(SessionKeys)
            Dim CustomerHeaderKey As PrimaryKey = EnterpriseUtils.VerifyDataRowKeys(ds.CustomerHeader.Rows(0), SessionKey, SubmitType)
            Dim OldCustomerHeaderKey As PrimaryKey = New PrimaryKey(CustomerHeaderKey)
            newkey = CustomerHeaderKey
            oldkey = OldCustomerHeaderKey

            If CustomerHeaderKey Is Nothing Then
                Return Nothing
            Else
                If ds.CustomerHeader.Rows.Count > 0 Then 'check if record was not deleted during update
                    CustomerHeaderKey.Update(ds.CustomerHeader(0))
                    If SubmitType = 1 Then
                        EnterpriseUtils.UpdateTemporaryLinks("CustomerNumber", CustomerHeaderKey, OldCustomerHeaderKey, "CustomerDetail", transaction)
                        EnterpriseUtils.UpdateTemporaryLinks("CustomerNumber", CustomerHeaderKey, OldCustomerHeaderKey, "CustomerMultiPayments", transaction)
                    End If


                    If callWrapper AndAlso ds.CustomerHeader(0).CustomerNumber.ToUpper <> "DEFAULT" Then
                        Dim Command As SqlCommand = New SqlCommand("enterprise.Customer_Control", Connection1)
                        Command.CommandType = CommandType.StoredProcedure
                        Command.Transaction = transaction
                        Dim parameter As SqlParameter
                        '@CompanyID
                        parameter = New SqlParameter("@CompanyID", SqlDbType.NVarChar, 36)
                        parameter.Value = ds.CustomerHeader(0).CompanyID
                        Command.Parameters.Add(parameter)
                        'DivisionID
                        parameter = New SqlParameter("@DivisionID", SqlDbType.NVarChar, 36)
                        parameter.Value = ds.CustomerHeader(0).DivisionID
                        Command.Parameters.Add(parameter)
                        '@DepartmentID
                        parameter = New SqlParameter("@DepartmentID", SqlDbType.NVarChar, 36)
                        parameter.Value = ds.CustomerHeader(0).DepartmentID
                        Command.Parameters.Add(parameter)
                        '@DocumentNumber
                        parameter = New SqlParameter("@DocumentNumber", SqlDbType.NVarChar, 36)
                        parameter.Value = ds.CustomerHeader(0).CustomerNumber
                        Command.Parameters.Add(parameter)
                        Command.ExecuteNonQuery()
                    End If
                End If
                transaction.Commit()
                transaction = Nothing
                Return CustomerHeaderKey.ToString()
            End If
        ElseIf ds.CustomerDetail.Count > 0 Then
            CustomerDetail_Adapter.Update(ds.CustomerDetail)
            transaction.Commit()
            transaction = Nothing
        ElseIf ds.CustomerMiscCharges.Count > 0 Then
            CustomerMiscCharges_Adapter.Update(ds.CustomerMiscCharges)
            transaction.Commit()
            transaction = Nothing
        ElseIf ds.CustomerMultiPayments.Count > 0 Then
            CustomerMultiPayment_Adapter.Update(ds.CustomerMultiPayments)
            transaction.Commit()
            transaction = Nothing
        End If
        Return Nothing       
    Catch e As SqlException
        errMsg = "Please contact your system administrator. (code number: " + e.Number + ")" 'Message + ")"
        WebUtils.ProcessError(e, errMsg, EDIErrorType.SendEmailNotification Or EDIErrorType.WriteLog)
        Return Nothing
    Catch e As Exception
        errMsg = e.Message
        WebUtils.ProcessError(e, errMsg, EDIErrorType.SendEmailNotification Or EDIErrorType.WriteLog)
        Return Nothing
    Finally
        If Not transaction Is Nothing Then
            transaction.Rollback()
        End If
        If Connection1.State = ConnectionState.Open Then
            Connection1.Close()
        End If
    End Try
End Function

任何人都能给我一些提示我做错了吗?

先谢谢。

1 个答案:

答案 0 :(得分:0)

您正在设置
 

之后的transaction = Nothing
transaction.Commit()

导致此问题的原因是,您需要在Finally Method之后将其设置为空。

Public Function PostCustomerSet(ByVal ds As CustomerHeaderDetailDataSet, ByVal Table As String, ByRef SessionKeys As String, ByRef errMsg As String, ByVal SubmitType As Integer, ByVal callWrapper As Boolean) As String
errMsg = Nothing
Dim newkey As PrimaryKey
Dim oldkey As PrimaryKey
Try
    transaction = EnterpriseUtils.StartTransaction(Connection1, m_Dict)
    If ds.CustomerHeader.Rows.Count > 0 Then
        Dim SessionKey As PrimaryKey = PrimaryKey.FromString(SessionKeys)
        Dim CustomerHeaderKey As PrimaryKey = EnterpriseUtils.VerifyDataRowKeys(ds.CustomerHeader.Rows(0), SessionKey, SubmitType)
        Dim OldCustomerHeaderKey As PrimaryKey = New PrimaryKey(CustomerHeaderKey)
        newkey = CustomerHeaderKey
        oldkey = OldCustomerHeaderKey

        If CustomerHeaderKey Is Nothing Then
            Return Nothing
        Else
            If ds.CustomerHeader.Rows.Count > 0 Then 'check if record was not deleted during update
                CustomerHeaderKey.Update(ds.CustomerHeader(0))
                If SubmitType = 1 Then
                    EnterpriseUtils.UpdateTemporaryLinks("CustomerNumber", CustomerHeaderKey, OldCustomerHeaderKey, "CustomerDetail", transaction)
                    EnterpriseUtils.UpdateTemporaryLinks("CustomerNumber", CustomerHeaderKey, OldCustomerHeaderKey, "CustomerMultiPayments", transaction)
                End If


                If callWrapper AndAlso ds.CustomerHeader(0).CustomerNumber.ToUpper <> "DEFAULT" Then
                    Dim Command As SqlCommand = New SqlCommand("enterprise.Customer_Control", Connection1)
                    Command.CommandType = CommandType.StoredProcedure
                    Command.Transaction = transaction
                    Dim parameter As SqlParameter
                    '@CompanyID
                    parameter = New SqlParameter("@CompanyID", SqlDbType.NVarChar, 36)
                    parameter.Value = ds.CustomerHeader(0).CompanyID
                    Command.Parameters.Add(parameter)
                    'DivisionID
                    parameter = New SqlParameter("@DivisionID", SqlDbType.NVarChar, 36)
                    parameter.Value = ds.CustomerHeader(0).DivisionID
                    Command.Parameters.Add(parameter)
                    '@DepartmentID
                    parameter = New SqlParameter("@DepartmentID", SqlDbType.NVarChar, 36)
                    parameter.Value = ds.CustomerHeader(0).DepartmentID
                    Command.Parameters.Add(parameter)
                    '@DocumentNumber
                    parameter = New SqlParameter("@DocumentNumber", SqlDbType.NVarChar, 36)
                    parameter.Value = ds.CustomerHeader(0).CustomerNumber
                    Command.Parameters.Add(parameter)
                    Command.ExecuteNonQuery()
                End If
            End If
            transaction.Commit()
            transaction = Nothing
            Return CustomerHeaderKey.ToString()
        End If
    ElseIf ds.CustomerDetail.Count > 0 Then
        CustomerDetail_Adapter.Update(ds.CustomerDetail)
        transaction.Commit()

    ElseIf ds.CustomerMiscCharges.Count > 0 Then
        CustomerMiscCharges_Adapter.Update(ds.CustomerMiscCharges)
        transaction.Commit()

    ElseIf ds.CustomerMultiPayments.Count > 0 Then
        CustomerMultiPayment_Adapter.Update(ds.CustomerMultiPayments)
        transaction.Commit()

    End If
    Return Nothing       
Catch e As SqlException
    errMsg = "Please contact your system administrator. (code number: " + e.Number + ")" 'Message + ")"
    WebUtils.ProcessError(e, errMsg, EDIErrorType.SendEmailNotification Or EDIErrorType.WriteLog)
    Return Nothing
Catch e As Exception
    errMsg = e.Message
    WebUtils.ProcessError(e, errMsg, EDIErrorType.SendEmailNotification Or EDIErrorType.WriteLog)
    Return Nothing
Finally
    If Not transaction Is Nothing Then
        transaction.Rollback()
    End If
    If Connection1.State = ConnectionState.Open Then
        Connection1.Close()
    End If
End Try
transaction = Nothing

结束功能