代码之家  ›  专栏  ›  技术社区  ›  CodingWithSpike

是否有创建ADO.NET连接并忽略环境事务的方法?

  •  4
  • CodingWithSpike  · 技术社区  · 17 年前

    我在一个wcf服务中运行,该服务的transactionscopererequired=true,这意味着总是有一个环境事务。

    但是,我需要启动一个新的连接,它将在应用程序的生命周期中一直存在,这意味着我不能让它使用abmbient事务。

    有什么办法吗?这样做将自动使用环境事务:

    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。在实际的代码中,在作用域内执行db操作的过程要多得多,我只有1个,我需要在事务作用域的生命周期内保持1个。


    我想真正的情况值得一提。这里实际发生的是,在WCF服务调用期间,我使用企业库缓存块将对象添加到缓存中。此对象是一个数据表,但也保留到已设置连续通知的Oracle的开放连接。这使我能够在基础Oracle表更改时自动刷新缓存的数据集。

    数据缓存项可以由任意数量的WCF初始化线程访问,所有线程都在各自的事务范围内运行。我想你可以把它看作是把一个OracleConnection对象放在缓存中。更好的文本/exampe代码块如下:

    //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
    }
    

    重点是,我有一个跨多个线程和事务作用域的长寿命连接。

    1 回复  |  直到 16 年前
        1
  •  5
  •   Jacob Proffitt    17 年前

    您是否尝试过允许您设置作用域的TransactionScope构造函数之一?将作用域设置为“Requires New”将创建一个新事务,以便您的连接登记。将作用域设置为“禁止”将使其不登记到任何事务中。至少,这就是我阅读文档的方式。我自己从未有过这种特殊的需要。

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