有没有办法创建 ADO.NET 连接并忽略环境事务?

发布于 2024-07-30 10:22:40 字数 1761 浏览 3 评论 0原文

我遇到过这样的情况:我在 TransactionScopeRequired=true 的 WCF 服务中运行,这意味着始终存在环境事务。

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

关于如何做到这一点有什么想法吗? 只要这样做就会自动使用环境事务:

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
}

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

I have a situation where I am running in a WCF service that has TransactionScopeRequired=true, which means there will always be an ambient transaction.

However, I need to start a new connection that will be around for the lifetime of the application, which means I can't have it use the abmbient transaction.

Any ideas on how to do this? Just doing this will automatically use the ambient transaction:

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

Actually the example could be made simpler by saying this:

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
}

I don't want my connection to actually pick up the TransactionScope. In the actual code there is a lot more going on that does do DB actions within the scope, I just have 1 that I need to keep around past the lifetime of the transaction scope.


I guess the real situation is worth mentioning. What actually happens here is that during a WCF service call, I add an object to a cache using the Enterprise Library Caching block. This object is a data table, but also holds on to an open connection to Oracle that has Continuous Notification set up. This gives me the ability to automatically refresh my cached dataset when the underlying Oracle tables change.

The data cache item can be accessed by any number of WCF initialized threads, all of which run in their own transaction scope. I guess you could think of it as putting an OracleConnection object in a cache. A better block of text/exampe code would be like:

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

Point being I have a connection that has a long lifetime across multiple threads and transaction scopes.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

无畏 2024-08-06 10:22:40

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

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

Have you tried one of the TransactionScope constructors that allows you to set the scope? Setting the scope to "Requires New" creates a new transaction for your connection to enlist in. Setting the scope to "Suppress" makes it so that your connection doesn't enlist in any transaction. At least, thats how I read the documentation. I've never had that specific need, myself.

using(var tx = new TransactionScope(TransactionScopeOption.RequiresNew))
{
    conn = new OracleConnection("my connection string");
    conn.Open();
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文