2008-11-21 9 views
11

Tengo un programa winform C# .net que se ejecuta con una base de datos SQL Server. Estoy usando LINQ-to-SQL. ¿Es posible deshacer la llamada a uno o más procedimientos almacenados dentro de una transacción dentro de mi programa usando LINQ-to-SQL?¿Retirar una llamada de procedimiento almacenado desde el interior de una transacción utilizando LINQ-to-SQL?

Inicialmente pensé que tendría sentido administrar la transacción dentro del procedimiento almacenado, pero si tuviera que deshacer más de una llamada a procedimiento almacenado como parte de una sola transacción, tendría que hacerlo en mi programa C#.

¿Alguien me puede indicar un fragmento de código sobre cómo hacer esto o dar una idea de una alternativa?

Respuesta

-1

aunque no estoy usando procedimientos almacenados, se desvivían por tener algo así:

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

Otra alternativa para DbTransaction es TransactionScope - esto proporciona un modelo de programación mucho más simple, y es extensible a múltiples bases de datos simultáneas y otras alimentaciones (a través de DTC), pero a costa de una pequeña cantidad de sobrecarga en la conexión. Lo que solía ser más sobrecarga, pero bajo SQL2005 etc se utilizará el "MLP" hasta que empezar abarca múltiples conexiones - por lo que una sola operación suele ser muy barato:

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

;-P Muy simple También debe ser capaz de hacer que la transacción sea más granular (en tan solo unas pocas consultas) o más que abarque muy simple. La mayoría de los códigos existentes se alistarán automáticamente en el alcance de la transacción, por lo que es muy fácil adaptarse al código existente.

Para obtener más información sobre TransactionScope (y las transacciones generales en .NET), consulte here.

+2

solo quiero aclarar un punto si no es obvio: "El método Complete confirma la transacción. Si se ha lanzado una excepción, complete no se llama y se retrotrae la transacción". (desde el primer enlace arriba) Por lo tanto, no busques un 'rollback()' y no tengas ninguna ruta de código que 'devuelva' sin 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; 

} 
Cuestiones relacionadas