【问题标题】:SqlTransaction has completed, it is no longer usable, rollback issueSqlTransaction 已完成,不再可用,回滚问题
【发布时间】:2017-03-01 04:17:54
【问题描述】:

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

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

谁能给我一些提示我做错了什么?

提前致谢。

【问题讨论】:

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


    【解决方案1】:

    你在设置
    transaction = Nothing之后

    transaction.Commit()
    

    导致此问题的原因,您需要在 finally 方法之后将其设置为空。

    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
    

    结束函数

    【讨论】:

    • 嗨,Rakesh,感谢您的反馈!我会尝试并告诉你
    • 嗨,Rakesh,我有一个问题想征求您的意见。我在 SQL 中的存储过程已经实现了回滚,在存储过程的末尾是这样的: WriteError: IF @@TRANCOUNT
    • 不,你应该很好,你不需要在代码中调用 BeginTrans 或 Rollback Trans。
    • 谢谢拉克什!非常感谢您的及时回复。
    • 当然,如果给定的解决方案有帮助,请将此回复标记为“答案很有帮助”。谢谢。
    猜你喜欢
    • 2014-11-17
    • 1970-01-01
    • 2011-09-15
    • 2020-01-19
    • 2011-03-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多