Сделки in.net


каковы рекомендации по выполнению транзакций в C# .Net 2.0. Какие классы следует использовать? Какие подводные камни нужно искать и т. д. Все эти фиксации и откаты. Я только начинаю проект, где мне нужно сделать некоторые операции при вставке данных в БД. Любые ответы или ссылки даже для основных вещей о транзакциях приветствуются.

5 130

5 ответов:

существует 2 основных вида транзакций; транзакции подключения и внешние транзакции. Транзакция соединения (например, SqlTransaction) привязана непосредственно к соединению с БД (например, SqlConnection), что означает, что вы должны продолжать передавать соединение вокруг - OK в некоторых случаях, но не позволяет использовать "create/use/release" и не позволяет работать с кросс-БД. Пример (форматированный для пространства):

using (IDbTransaction tran = conn.BeginTransaction()) {
    try {
        // your code
        tran.Commit();
    }  catch {
        tran.Rollback();
        throw;
    }
}

не слишком грязно, но ограничивается нашим соединением "conn". Если мы хотите вызвать различные методы, теперь нам нужно передать "conn" вокруг.

альтернативой является внешняя транзакция; новый в .NET 2.0,TransactionScope

protected void Button1_Click(object sender, EventArgs e)
   {


       using (SqlConnection connection1 = new SqlConnection("Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\Database.mdf;Integrated Security=True;User Instance=True"))
       {
           connection1.Open();

           // Start a local transaction.
           SqlTransaction sqlTran = connection1.BeginTransaction();

           // Enlist a command in the current transaction.
           SqlCommand command = connection1.CreateCommand();
           command.Transaction = sqlTran;

           try
           {
               // Execute two separate commands.
               command.CommandText =
                "insert into [doctor](drname,drspecialization,drday) values ('a','b','c')";
               command.ExecuteNonQuery();
               command.CommandText =
                "insert into [doctor](drname,drspecialization,drday) values ('x','y','z')";
               command.ExecuteNonQuery();

               // Commit the transaction.
               sqlTran.Commit();
               Label3.Text = "Both records were written to database.";
           }
           catch (Exception ex)
           {
               // Handle the exception if the transaction fails to commit.
               Label4.Text = ex.Message;


               try
               {
                   // Attempt to roll back the transaction.
                   sqlTran.Rollback();
               }
               catch (Exception exRollback)
               {
                   // Throws an InvalidOperationException if the connection 
                   // is closed or the transaction has already been rolled 
                   // back on the server.
                   Label5.Text = exRollback.Message;

               }
           }
       }


   }

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

Если вам просто нужно это для связанных с БД вещей, некоторые или картографы (например, NHibernate) поддерживают transactinos из коробки по умолчанию.

Это также зависит от того, что вам нужно. Для базовых транзакций SQL вы можете попробовать выполнить транзакции TSQL, используя BEGIN TRANS и COMMIT TRANS в своем коде. Это самый простой способ, но он имеет сложность, и вы должны быть осторожны, чтобы совершить правильно (и откат).

Я бы использовал что-то вроде

SQLTransaction trans = null;
using(trans = new SqlTransaction)
{
    ...
    Do SQL stuff here passing my trans into my various SQL executers
    ...
    trans.Commit  // May not be quite right
}

любая неудача вытолкнет вас прямо из using и транзакция всегда будет фиксироваться или откатываться (в зависимости от того, что вы ей скажете). Этот самая большая проблема, с которой мы столкнулись, была убедиться, что она всегда совершается. Использование гарантирует, что объем транзакции ограничен.