2

我正在尝试在分布式事务下更新 DB2 数据库(通过 NHibernate),但它一直失败。

这是我写的代码:

public bool ExecuteUsingDTC(List<Func<bool>> tasks)
{
    var result = false;
    using (var scope = new TransactionScope(TransactionScopeOption.Required))
    {
        using (var session = sessionFactory.OpenSession())
        using (var transaction = session.BeginTransaction())
        {
            //carry out db modification tasks
            tasks.ForEach(task => { result = result && task.Invoke(); })
            transaction.Commit();
        }
        scope.Complete();
    }

    return result;
}

我不断收到异常:

NHibernate.TransactionException was unhandled by user code
Message=Begin failed with SQL exception
Source=NHibernate
StackTrace:
   at NHibernate.Transaction.AdoTransaction.Begin(IsolationLevel isolationLevel)
   at NHibernate.Transaction.AdoTransaction.Begin()
   at NHibernate.AdoNet.ConnectionManager.BeginTransaction()
   at NHibernate.Impl.SessionImpl.BeginTransaction()
   at DTCProofOfConcept_Repository.ExecuteUsingDTC(List`1 tasks) in C:\Project\Infrastructure\GlobalRepositories\DTCProofOfConcept_Repository.vb:line 20
   at 

InnerException: IBM.Data.DB2.DB2Exception
   ErrorCode=-2147467259
   Message=ERROR [HY011] [IBM] CLI0126E  Operation invalid at this time. SQLSTATE=HY011
   Source=IBM.Data.DB2
   StackTrace:
        at IBM.Data.DB2.DB2Connection.HandleError(IntPtr hHandle, SQL_HANDLE hType, RETCODE retcode)
        at IBM.Data.DB2.DB2Transaction.set_AutoCommit(Boolean value)
        at IBM.Data.DB2.DB2Transaction.BeginTransaction()
        at IBM.Data.DB2.DB2Connection.BeginTransactionObject(IsolationLevel isolevel)
        at IBM.Data.DB2.DB2Connection.BeginTransaction(IsolationLevel isolevel)
        at IBM.Data.DB2.DB2Connection.BeginTransaction()
        at IBM.Data.DB2.DB2Connection.System.Data.IDbConnection.BeginTransaction()
        at NHibernate.Transaction.AdoTransaction.Begin(IsolationLevel isolationLevel)
   InnerException: 
4

1 回答 1

1

像这样使用 TransactionScope

using(var scope = new TransactionScope(...))
{

    transaction.Complete();
}

开始并为您提交事务。如果抛出异常,则事务将被正在处理的范围中止,而不会调用 Complete。

我怀疑您的问题是您对 BeginTransaction/Commit 有一个额外的显式调用。删除这些并假设 NHibernate 可以很好地与 TransactionScope 一起使用应该没问题。

使用 TransactionScope 可能涉及使用分布式事务协调器 (DTC)。如果是这样,您需要打开管理工具|组件服务。导航到分布式事务协调器|本地 DTC。右键,属性,安全选项卡。启用安全性并作为开始启用一切。如果这可行,请阅读 DTC 安全性并将其减少到最低限度。

或者按照 DanVallejo 的建议删除 TransactionScope 并使用您的显式事务。

于 2012-04-30T21:36:00.740 回答