Есть ли способ создать соединение ADO.NET и игнорировать внешнюю транзакцию? - PullRequest
4 голосов
/ 01 августа 2009

У меня есть ситуация, когда я работаю в службе WCF с TransactionScopeRequired = true, что означает, что всегда будет транзакция окружения.

Однако мне нужно установить новое соединение, которое будет существовать на протяжении всего жизненного цикла приложения, а это значит, что я не могу использовать его для исходящей транзакции.

Есть идеи, как это сделать? Просто сделав это, вы автоматически используете транзакцию ambient:

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. Этот объект является таблицей данных, но также поддерживает открытое соединение с 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
}

Суть в том, что у меня есть соединение с большим временем жизни в нескольких потоках и областях транзакций.

1 Ответ

5 голосов
/ 01 августа 2009

Вы пробовали один из конструкторов TransactionScope, который позволяет вам установить область? Установка области «Требуется новая» создает новую транзакцию для подключения к ней. Настройка области «Подавить» делает так, чтобы ваше подключение не подключалось ни к одной транзакции. По крайней мере, так я читаю документацию. У меня никогда такой особой потребности не было.

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