NHibernate 事务提交失败

NHibernate transactions commit failed

在生产中,我在提交 Nhibernate 事务期间遇到了偶发性超时异常。但是我期望更新的记录是正确的! 在舞台环境中没有什么可报告的。

下面是我的批处理程序的应用日志。

ERROR 2015-06-25 01:32:01,165 SRV-IIS03  Commit failed
System.Data.SqlClient.SqlException (0x80131904): Timeout expired.  The    timeout period elapsed prior to completion of the operation or the server is not    responding.
at System.Data.SqlClient.SqlConnection.OnError(SqlException exception,  Boolean breakConnection)
at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection)
at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning()
at System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand   cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler,   TdsParserStateObject stateObj)
at System.Data.SqlClient.TdsParser.TdsExecuteTransactionManagerRequest(Byte[]  buffer, TransactionManagerRequestType request, String transactionName,  TransactionManagerIsolationLevel isoLevel, Int32 timeout, SqlInternalTransaction  transaction, TdsParserStateObject stateObj, Boolean isDelegateControlRequest)
at System.Data.SqlClient.SqlInternalConnectionTds.ExecuteTransactionYukon(Transacti onRequest transactionRequest, String transactionName, IsolationLevel iso,  SqlInternalTransaction internalTransaction, Boolean isDelegateControlRequest)
at System.Data.SqlClient.SqlInternalConnectionTds.ExecuteTransaction(TransactionReq uest transactionRequest, String name, IsolationLevel iso, SqlInternalTransaction  internalTransaction, Boolean isDelegateControlRequest)
at System.Data.SqlClient.SqlInternalTransaction.Commit()
at System.Data.SqlClient.SqlTransaction.Commit()
at NHibernate.Transaction.AdoTransaction.Commit()

ERROR 2015-06-25 01:32:01,431 SRV-IIS03  Errore imprevisto nel metodo  Run:NHibernate.TransactionException: Commit failed with SQL exception --->  System.Data.SqlClient.SqlException: Timeout expired.  The timeout period elapsed prior to completion of the operation or the server is not responding.
at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection)
at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection)
at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning()
at System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj)
at System.Data.SqlClient.TdsParser.TdsExecuteTransactionManagerRequest(Byte[] buffer, TransactionManagerRequestType request, String transactionName, TransactionManagerIsolationLevel isoLevel, Int32 timeout, SqlInternalTransaction transaction, TdsParserStateObject stateObj, Boolean isDelegateControlRequest)
at System.Data.SqlClient.SqlInternalConnectionTds.ExecuteTransactionYukon(TransactionRequest transactionRequest, String transactionName, IsolationLevel iso, SqlInternalTransaction internalTransaction, Boolean isDelegateControlRequest)
at System.Data.SqlClient.SqlInternalConnectionTds.ExecuteTransaction(TransactionRequest transactionRequest, String name, IsolationLevel iso, SqlInternalTransaction internalTransaction, Boolean isDelegateControlRequest)
at System.Data.SqlClient.SqlInternalTransaction.Commit()
at System.Data.SqlClient.SqlTransaction.Commit()
at NHibernate.Transaction.AdoTransaction.Commit()
--- End of inner exception stack trace ---
at NHibernate.Transaction.AdoTransaction.Commit()
at [omit].Run(String[] args) in [omit].cs:line 153

ERROR 2015-06-25 01:32:01,493 SRV-IIS03  Errore imprevisto nel batch    [omit]: NHibernate.TransactionException: Transaction not successfully started
at NHibernate.Transaction.AdoTransaction.CheckBegun()
at NHibernate.Transaction.AdoTransaction.Rollback()
at [omit].RollbackTransazione() in [omit].cs:line 212
at [omit].Run(String[] args) in [omit].cs:line 159
at [omit].Main(String[] args) in [omit].cs:line 29  

下面是我的批次结构

    private static ITransaction tx;

    public virtual BatchResponseStatus Run(string[] args)
    {
        var response = BatchResponseStatus.Success;

        try
        {
            //Do some stuff 

            SetTransaction();

            //Collect elements to be processed

            foreach (var item in aListOfItem)
            {
                // Stuff

                // Call methods that creates, reads  or updates records 
                // with Fluent Nhibernate or Sql Server Stored procedure

                // Write some files 

                // Zip files

                // Update DTO
            }

            tx.Commit();
        }
        catch (Exception ex)
        { 
            RollbackTransaction();
            XXRepository.NhSession.Clear();
            response = BatchResponseStatus.Error;
        }
        finally
        {
            DisposeTransaction();
        }

        return response; 
    }

    private void SetTransaction()
    {
        tx = XXRepository.NhSession.BeginTransaction(IsolationLevel.ReadUncommitted);

        if (tx == null)
                throw new Exception("Impossible create a Transaction");
    }

    private static void RollbackTransaction()
    {
        if (tx != null)
        {
            tx.Rollback();
        }
    }

我使用这项技术:

有人可以帮助我吗? 谢谢

连接超时。这意味着,连接超时,但在 Sql 服务器中继续提交。正如您在日志中所见,回滚失败,因为连接已提交。恕我直言,Sql客户端实现未正确处理连接超时。

有一个 forum thread 讨论了这个问题。