2008-11-21 12 views
11

Mam program WinForm C# .net, który działa z bazą danych SQL Server. Używam LINQ-SQL. Czy jest możliwe wycofanie wywołania do jednej lub wielu procedur przechowywanych wewnątrz transakcji w ramach mojego programu przy użyciu LINQ-SQL?Wycofuje wywołanie procedury przechowywanej z poziomu transakcji za pomocą LINQ-SQL?

Początkowo myślałem, że sensownym będzie zarządzanie transakcją wewnątrz procedury przechowywanej, ale jeśli potrzebuję wycofać więcej niż jedno wywołanie procedury składowanej jako część pojedynczej transakcji, musiałbym to zrobić w moim programie C#.

Czy ktoś może wskazać mi fragment kodu, jak to zrobić, lub podać jakiś wgląd w alternatywę?

Odpowiedz

-1

Chociaż ja nie używając przechowywanych procs, coudl masz coś takiego:

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; 
      } 
     } 
15

Inną alternatywą DbTransaction jest TransactionScope - zapewnia to znacznie prostszy model programowania i jest rozszerzalny do wielu jednoczesnych baz danych i inne kanały (za pośrednictwem DTC) - ale kosztem niewielkiej nadwyżki na połączeniu. Kiedyś to dodatkowe koszty, ale pod SQL2005 etc będzie użyć „LTM”, aż zacznie obejmujących wiele połączeń - tak pojedyncza operacja jest zwykle bardzo tanie:

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

Bardzo prosty ;-P Powinieneś także być w stanie uczynić transakcję bardziej szczegółową (za zaledwie kilka zapytań) lub objąć ją w bardzo prosty sposób. Większość istniejącego kodu zostanie automatycznie zarejestrowana w zakresie transakcji, dzięki czemu bardzo łatwo dopasuje się do istniejącego kodu.

Aby uzyskać więcej informacji na temat transakcji TransactionScope (i ogólnych transakcji w .NET), zobacz here.

+2

prostu chcę wyjaśnić jeden punkt, jeśli jej nie oczywiste: „The Complete metoda zatwierdza transakcję Jeśli wyjątek został rzucony, kompletne nie nazywa, a transakcja zostanie wycofana.”. (od pierwszego linku powyżej) Więc nie idź szukać 'rollback()' i nie masz żadnych ścieżek kodu, które 'zwracają' bez Complete() –

-2
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; 

} 
Powiązane problemy