c # получить текущее соединение в транзакции TransactionScope - PullRequest
3 голосов
/ 15 сентября 2010

Я хочу сделать транзакцию серией вызовов sp (sql server 2005) в проекте .net 2.0, окружающих некоторую часть бизнес-логики

.
using(TransactionScope...)

К сожалению, я унаследовал DAL от другого проекта и не хочу вносить в него много изменений ... проблема в том, что каждый метод, который вызывает хранимую процедуру, открывает новое соединение.

Итак, мой вопрос: есть ли способ получить соединение, используемое текущей транзакцией, то есть из Transaction.Current ??

Спасибо

s.

ОБНОВЛЕНИЕ: Скажите, пожалуйста, что не так с этим консольным приложением (версия 2005, .net 2.0, Sql server 2005)

using System;
using System.Collections.Generic;
using System.Text;
using System.Data.SqlClient;
using System.Data;
using System.Transactions;

namespace ConsoleApplication1
{
    public class Program
    {
        static void Main(string[] args)
        {
            using (TransactionScope ts = new TransactionScope(TransactionScopeOption.Required))
            {
                Console.WriteLine("1");
                test();
                Console.WriteLine("2");
                test();
            }
            Console.WriteLine("END");
        }

        public static void test()
        {
            string connectionString = @"Persist Security Info=True;User ID=usr123;Password=123;Initial Catalog=db123;Data Source=myserver\myinstance;Connect Timeout=180;";

            using (SqlConnection conn = new SqlConnection(connectionString))
            {
                conn.Open();
            }
        }
    }
}

Ответы [ 3 ]

1 голос
/ 16 сентября 2010

ОК, пара вещей:

  1. Я сомневаюсь, что TransactionScope даже имеет понятие (Sql) Connection. Причина в том, что он работает со всеми видами транзакционных ресурсов, будь то база данных, система очередей сообщений или что-то еще. Вы можете обратиться к Документам MSDN для System.Transactions для получения дополнительной информации. Итак, я думаю, ваш подход обречен на провал с самого начала.

  2. В вашем примере вы пропускаете вызов ts.Complete (), таким образом, ваша (распределенная) транзакция всегда будет откатываться после завершения использования-Scope. Это не имеет отношения к описываемой вами проблеме, но, тем не менее, на это стоит обратить внимание.

  3. Ваша внешняя транзакция, похожая на экземпляр TransactionScope, распространяется на распределенную транзакцию, поскольку внутри нее используется более одного соединения. По сути, DTC в вашей системе должен взаимодействовать с DTC на сервере базы данных. Для этого оба должны быть правильно настроены.

Чтобы настроить DTC, запустите консоль управления «Службы компонентов», выполнив g C:\Windows\System32\com\comexp.msc. В древовидном меню перейдите к «Службы компонентов \ Компьютеры \ Мой компьютер». В контекстном меню откройте «Свойства». В диалоговом окне свойств выберите вкладку «MSDTC», на ней нажмите кнопку «Конфигурация безопасности ...».

В диалоговом окне убедитесь, что выбраны следующие параметры:

  • «Сетевой доступ к DTC»
  • «Разрешить удаленных клиентов»
  • «Разрешить входящий»
  • «Разрешить исходящий»
  • «Включить транзакции по протоколу TIP»
  • «Включить транзакции XA»

(Примечание: некоторые из них на самом деле могут и не понадобиться, YMMV) * ​​1038 *

Возможно, вы также захотите установить «Аутентификация не требуется», в зависимости от ваших локальных политик / требований.

Вам нужно сделать это на обеих системах: на той, на которой работает ваше приложение, и на той, что содержит базу данных.

1 голос
/ 17 сентября 2010

Хорошо, спасибо всем .. .. наконец я закончил писать что-то вроде Microsoft.Practices.EnterpriseLibrary.Data.TransactionScopeConnections, которые вы можете найти в Enterprise Library (http://entlib.codeplex.com) ..

0 голосов
/ 15 сентября 2010

Если вы по какой-то причине не используете пул соединений, нет веской причины не просто обновлять SqlConnection и отправляться в город.Позвольте среде выполнения обработать детали создания этого исполнителя - для этого нужен пул соединений.Похоже, что DAL написан правильно:

...
using (var conn = new SqlConnection("connection string"))
{
    using (var cmd = conn.CreateCommand())
    {
        conn.Open();
        //Do stuff with cmd
    }
}
....

Даже если вы не используете пул соединений (и у вас есть веская причина этого не делать), лучший путь, вероятно, все еще будетНовый SqlConnection и отправиться в город.Вы не хотите случайно что-то сделать, например, закрыть соединение, используемое областью транзакции, и при этом предполагается, что оно на самом деле имеет SqlConnection для ссылки.

...