c# - 如何使用交易范围?

标签 c# .net db2 transactionscope distributed-transactions

我试图在分布式事务下更新 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: 

最佳答案

像这样使用 TransactionScope

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

    transaction.Complete();
}

开始并为您提交交易。如果抛出异常,则事务将在未调用 Complete 的情况下被释放的范围中止。

我怀疑您的问题是您对 BeginTransaction/Commit 进行了额外的显式调用。删除那些并假设 NHibernate 与 TransactionScope 配合得很好,一切都应该没问题。

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

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

关于c# - 如何使用交易范围?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10390680/

相关文章:

.NET 命名空间子目录

c# - 如何将此字符数组参数从 C 编码为 C# 中的字符串?

java - 如何用参数化查询的方式处理SQL Statement中 'IN'的情况?

python - 使用 python 连接到 DB2

java - 有没有办法在外部而不是 "db2jcc_application"的 DB2 连接上设置 APPL_NAME(例如,使用系统属性)

c# - Windows Phone 8.0 证书固定

c# - 添加到 ObservableCollection - 对象引用错误

c# - 空路径名不合法

c# - 无法为接受 Expression<Func> 的方法推断实际类型

asp.net - 异步/等待和异步 Controller ?