【问题标题】:Is there a way to create an ADO.NET connection and ignore the ambient Transaction?有没有办法创建 ADO.NET 连接并忽略环境事务?
【发布时间】:2009-07-31 21:10:10
【问题描述】:

我在 WCF 服务中运行的情况是 TransactionScopeRequired=true,这意味着总会有环境事务。

但是,我需要在应用程序的整个生命周期内启动一个新连接,这意味着我不能让它使用环境事务。

关于如何做到这一点的任何想法?这样做会自动使用环境事务:

Assert.IsNotNull(System.Transactions.Transaction.Current);
var conn = new OracleConnection("my connection string");
conn.Open(); // <-- picks up ambient transaction, but I don't want that

实际上,这样说可以使示例更简单:

OracleConnection conn; // <-- this is actually held around in another object that has a very long lifetime, well past the TransactionScope.
using(var tx = new TransactionScope())
{
    conn = new OracleConnection("my connection string");
    conn.Open(); // <-- picks up ambient transaction, but I don't want that
    // ... do stuff
}

我不希望我的连接实际获取 TransactionScope。在实际代码中,在范围内执行数据库操作的还有很多事情要做,我只有 1 个需要在事务范围的生命周期之后保留。


我想真实情况值得一提。这里实际发生的是,在 WCF 服务调用期间,我使用 Enterprise Library Caching 块将对象添加到缓存中。该对象是一个数据表,但也保持与已设置持续通知的 Oracle 的打开连接。这使我能够在底层 Oracle 表发生更改时自动刷新我的缓存数据集。

数据缓存项可以被任意数量的 WCF 初始化线程访问,所有这些线程都在它们自己的事务范围内运行。我想您可以将其视为将 OracleConnection 对象放入缓存中。更好的文本/示例代码块如下:

//beginning of a WCF service call
using (var tx = new TransactionScope())
{
    var conn = new OracleConnection();
    var cmd = new OracleCommand();
    // set up OCN on the cmd and connection
    var reader = cmd.ExecuteReader();
    cache.Add("conn", conn);
    cache.Add("cmd", cmd);
}

//beginning of a second wcf service call
using (var tx = new TransactionScope())
{
    var conn = cache.Get("conn");
    var cmd = cache.Get("cmd");
    var reader = cmd.ExecuteReader();
    // user reader to reload some data
}

重点是我的连接在多个线程和事务范围内具有较长的生命周期。

【问题讨论】:

    标签: c# .net ado.net transactions transactionscope


    【解决方案1】:

    您是否尝试过允许您设置范围的 TransactionScope 构造函数之一?将范围设置为“需要新的”会为您的连接创建一个新事务以供登记。将范围设置为“抑制”可以使您的连接不会在任何事务中登记。至少,这就是我阅读文档的方式。我自己从来没有这种特殊需求。

    using(var tx = new TransactionScope(TransactionScopeOption.RequiresNew))
    {
        conn = new OracleConnection("my connection string");
        conn.Open();
    }
    

    【讨论】:

    • 不知何故我错过了构造函数参数,谢谢!有趣的是,使用 .Suppress 会导致我的应用程序在调用 OracleCommand.ExecuteReader() 时似乎永远挂起。可能是因为 TransactionScope 块在 ExecuteReader 调用之前结束。 (在我的 OP 中添加了注释)
    猜你喜欢
    • 2020-05-10
    • 2020-12-28
    • 2021-03-27
    • 2011-04-30
    • 2020-07-02
    • 1970-01-01
    • 2012-11-30
    • 2020-04-28
    • 1970-01-01
    相关资源
    最近更新 更多