Распространенный способ работы с транзакциями в C # - PullRequest
0 голосов
/ 19 ноября 2010

Как вы используете транзакции в своем коде?

Старый добрый способ состоял в том, чтобы сделать что-то подобное:

try
{
    IDbTransaction tx = Connection.BeginTransaction();
    perform_work1
    perform_work2
    perform_work3
    tx.Commit();

}
catch(DbException)
{
   tx.Rollback();
   throw;
}

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

Первая идея - сделать что-то похожее на это:

public static class SafeCallerProxy
    {
        public delegate T ResultativeAction<T>();

        public static T ExecuteWithResult<T>(IDbConnection conn, ResultativeAction<T> action)
        {
            using(IDbTransaction tx = conn.BeginTransaction())
            {
                try
                {
                    T result = action();
                    tx.Commit();
                    return result;
                }
                catch (System.Data.DataException)
                {
                    tx.Rollback();
                    throw;
                }
            }
        }

        public static void ExecuteAction(IDbConnection conn, Action action)
        {
            using (IDbTransaction tx = conn.BeginTransaction())
            {
                try
                {
                    action();
                    tx.Commit();
                }
                catch (System.Data.DataException)
                {
                    tx.Rollback();
                    throw;
                }
            }
        }
    }

использование

SafeCallerProxy.ExecuteAction(connection, () => 
{
  DoWork1();
  DoWork2();
  DoWork3();
}
);

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

Извините за мой английский.

Ответы [ 3 ]

1 голос
/ 19 ноября 2010

Я использую LINQ to Entities, который обрабатывает транзакции для меня. Я полагаю, было бы довольно легко добавить автоматическое ведение журнала с использованием шаблона T4.

1 голос
/ 19 ноября 2010

Лично я использую NHibernate с Spring.NET , который имеет поддержку AOP , поэтому я в основном определяю во внешнем файле конфигурации, какие методы я хотел бы выполнить под Транзакция SQL Обычно это мои сервисные методы, которые в терминах могут вызывать несколько методов доступа к данным, которые я хотел бы запустить в одной транзакции.

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

0 голосов
/ 19 ноября 2010

Если я не ошибаюсь, я думаю, вы можете предположить, что объект транзакции, реализующий интерфейс IDbTransaction, выполнит откат, если он будет удален до вызова метода Commit. Конечно, это не гарантия, но я думаю, что это будет плохая реализация, если не будет реализована таким образом.

Учитывая это, я бы написал ваш пример просто так:

        using (var tx = connection.BeginTransaction())
        {
            DoWork1();
            DoWork2();
            DoWork3();
            tx.Commit();
        }

если бы мне нужно было перехватывать и регистрировать исключения из базы данных, я бы обернул весь блок using в try / catch:

        try
        {
            using (var tx = connection.BeginTransaction())
            {
                DoWork1();
                DoWork2();
                DoWork3();
                tx.Commit();
            }
        }
        catch (DataException ex)
        {
            // log ex
        }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...