Откатить вызов хранимой процедуры из транзакции, используя LINQ-to-SQL? - PullRequest
11 голосов
/ 21 ноября 2008

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

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

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

Ответы [ 3 ]

15 голосов
/ 21 ноября 2008

Другой альтернативой 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) см. здесь .

0 голосов
/ 21 мая 2009
private string RollBack_fn()
{
    int sal = 0;
    OracleConnection myconn = new OracleConnection(ConfigurationManager.AppSettings["con"].ToString());
    cmd = new OracleCommand("SP_student_MAST", myconn);
    cmd.CommandType = CommandType.StoredProcedure;
    OracleParameter param1 = null, param2 = null, param3 = null, param4 = null, param5 = null;

    try
    {
        myconn.Open();
       trans = myconn.BeginTransaction();
        cmd.Transaction = trans;
        //param1 = new OracleParameter("pSNo", OracleType.VarChar, 5);
        //param1.Value ="";
        //cmd.Parameters.Add(param1);

        param2 = new OracleParameter("pSName", OracleType.VarChar, 10);
       // param2.Value = "Saravanan";
        param2.Value = TextBox1.Text;
        cmd.Parameters.Add(param2);

        param3 = new OracleParameter("pENo", OracleType.VarChar,5);
        param3.Value = TextBox2.Text;
        cmd.Parameters.Add(param3);

        param4 = new OracleParameter("pEName", OracleType.VarChar,10);
       // param4.Value = "Sangeetha";
        param4.Value = TextBox3.Text;
        cmd.Parameters.Add(param4);

        param5 = new OracleParameter("pSENo", OracleType.Char, 5);
        param5.Value = "";
        cmd.Parameters.Add(param5);
        sal = cmd.ExecuteNonQuery();
        trans.Commit();
        Response.Write("Record Saved");
        myconn.Close();
       // rollbackvalue = 0;
    }
    catch (Exception ex)
    {
        Response.Write("Not saved.RollBacked");
        trans.Rollback();
        //rollbackvalue = 1;
    }
    string cs = Convert.ToString(sal);
    return cs;

}
0 голосов
/ 21 ноября 2008

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

    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;
            }
        }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...