Откатить вызов хранимой процедуры из транзакции с помощью LINQ-to-SQL?

У меня есть программа C#.net winform, которая работает с базой данных SQL Server. Я использую LINQ-to-SQL. Можно ли отменить вызов одной или нескольких хранимых процедур внутри транзакции в моей программе с помощью LINQ-to-SQL?

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

Может ли кто-нибудь указать мне фрагмент кода о том, как это сделать, или дать некоторое представление об альтернативе?


person Community    schedule 21.11.2008    source источник


Ответы (2)


Другой альтернативой DbTransaction является TransactionScope - это обеспечивает гораздо более простую модель программирования и расширяется до нескольких одновременных баз данных и других каналов (через DTC), но за счет небольших накладных расходов на соединение. Раньше это было более накладно, но в SQL2005 и т. Д. Он будет использовать «LTM», пока вы не начнете охватывать несколько соединений, поэтому одна операция обычно очень дешева:

using (TransactionScope tran = new TransactionScope())
using (FooDataContext ctx = new FooDataContext())
{
    // your work with ctx
    // ...
    // other work involving connections etc
    // ...
    tran.Complete();
}

Очень просто ;-p Вы также должны иметь возможность сделать транзакцию более детализированной (всего за несколько запросов) или более простой. Большая часть существующего кода будет автоматически добавлена ​​в область транзакции, что позволит легко встроить его в существующий код.

Дополнительные сведения о TransactionScope (и общих транзакциях в .NET) см. здесь.

person Community    schedule 21.11.2008
comment
просто хочу уточнить один момент, если это не очевидно: метод Complete фиксирует транзакцию. Если возникло исключение, метод complete не вызывается и транзакция откатывается. (из первой ссылки выше) Так что не ищите «rollback()» и не имейте путей кода, которые «возвращают» без Complete() - person Simon_Weaver; 25.11.2009

Хотя я не использую хранимые процедуры, у вас может быть что-то вроде этого:

    public Response<SomeObject> SaveSomething(Object yourObject)
    {
        DbTransaction dbTransaction = null;
        try
        {
            using (DataContext context = new DataContext())
            {
                    //Creates a new DB transaction
                    if (context.Connection.State == System.Data.ConnectionState.Closed)
                    {
                        context.Connection.Open();
                    }
                    dbTransaction = context.Connection.BeginTransaction(System.Data.IsolationLevel.Serializable);
                    context.Transaction = dbTransaction;

         context.SaveYourObject(yourObject);
                    //Commit the transaction
                    dbTransaction.Commit();
                    response.ResponseObject = yourObject;
                    response.Messages.AddSuccessfulSave("Saved!");
                }
            }
        }
        catch (ChangeConflictException cex)
        {
            if (dbTransaction != null) dbTransaction.Rollback();
            response.Errors.AddConcurrencyError();
            response.IsSuccessful = false;
        }
        catch (SqlException sqlEx)
        {
            if (dbTransaction != null) dbTransaction.Rollback();
            if (sqlEx.Class == 14 && (sqlEx.Number == 2601 || sqlEx.Number == 2627)) //Duplicated key
            {
                response.Errors.Add(new Error
                {
                    Name = "Duplicate item",
                    Description = "This object already exists."
                });
                ExceptionPolicy.HandleException(sqlEx, SERVICE_EXCEPTION_POLICY);
                response.IsSuccessful = false;
            }
            else //other SQL errors
            {
                response.Errors.AddSavingError("Your object", yourObjectId);
                ExceptionPolicy.HandleException(sqlEx, SERVICE_EXCEPTION_POLICY);
                response.IsSuccessful = false;
            }
        }
person Community    schedule 21.11.2008