DbTransaction, transaciones en un Db Factory

by Valeriano Tortola 16. septiembre 2007 21:08

Siguiendo con el tema del DbFactory con las clases de System.Data.Common, que permiten trabajar con cualquier base de datos de la que tengamos un proveedor en .NET, explicaré la clase DbTransaction, el cual permite realizar transacciones en la base de datos (explicación más completa en la versión en inglés).

Una transacción es una operación formada por un grupo de operaciones relacionadas, cada una podría requerir varias operaciones de lectura y/ó escritura en la base de datos, y solo tiene validez si se ejecutan todas. En caso de producirse un error en el transcurso de la transacción, ha de ser posible “deshacer” todas las operaciones anteriores (rollback), en caso contrario se da por finalizada la transacción aplicando los cambios (commit).

Por ejemplo, en un traspaso de dinero entre dos cuentas del mismo banco, la operación incluye primero la substracción del dinero de la cuenta A y su ingreso en la cuenta B, imaginemos que la substracción se realiza correctamente pero hay un error a la hora de ingresar la cantidad en B, en este caso el dinero no quedaría ni en una cuenta ni en otra y podría hasta “perderse”; si esta operación se ejecuta como una transacción, al fallar el ingreso en B, automáticamente se revertiría la substracción en A, con lo que ambas cuentas volverían a quedar en el mismo estado que antes de ejecutarse dicha transacción.

Siguiendo con el ejemplo anterior en DbFactory y volviendo a usar la misma base de datos de ejemplo Northwind que viene incluida en SQL Server 2005 Express, en este ejemplo se realizará la inserción de 5 nuevos empleados como una transacción, si todo funciona correctamente se realizará un DbTransaction.Commit() que finalizaría la transacción guardando los datos, mientras que si en el transcurso de la operación se produjese alguna excepción, se ejecutaría DbTransaction.Rollback() devolviendo a la tabla a su estado original. A partir de este código probad a introducir errores en las sentencias SQL para ver como al saltar una DbException se realiza un rollback.

 

string provider = ConfigurationManager.ConnectionStrings["SQLServer"].ProviderName;
string connectionString = ConfigurationManager.ConnectionStrings["SQLServer"].ConnectionString;
// Sentencia SQL
string insertEmployee = 
  "INSERT INTO EMPLOYEES (EmployeeID, LastName, FirstName) VALUES ({0}, ‘{1}’, ‘{2}’)";
// Obtengo el proovedor.
DbProviderFactory dbpf = DbProviderFactories.GetFactory(provider);
// Creo la conexión y el comando.
using (DbConnection dbcon = dbpf.CreateConnection())
using (DbCommand dbcmd = dbcon.CreateCommand())
{
// Configuro la conexión
dbcon.ConnectionString = connectionString;
try
{
  // Abro la conexión
  dbcon.Open();
  // Inicio la transación
  dbcmd.Transaction = dbcon.BeginTransaction();
  // Si os falla al insertar filas probad esto:
  dbcmd.CommandText = "SET IDENTITY_INSERT Employees ON";
  dbcmd.ExecuteNonQuery();
  ////
  // Inserto a los nuevos empleados
  dbcmd.CommandText = string.Format(insertEmployee, 10, "Simpson", "Homer");
  dbcmd.ExecuteNonQuery();
  dbcmd.CommandText = string.Format(insertEmployee, 11, "Szyslak", "Moe");
  dbcmd.ExecuteNonQuery();
  dbcmd.CommandText = string.Format(insertEmployee, 12, "Carlson", "Karl");
  dbcmd.ExecuteNonQuery();
  dbcmd.CommandText = string.Format(insertEmployee, 13, "Leonard", "Lenny");
  dbcmd.ExecuteNonQuery();
  dbcmd.CommandText = string.Format(insertEmployee, 14, "Gamble", "Barney");
  dbcmd.ExecuteNonQuery();
  // No ha saltado ninguna excepción,
  // todo ha ido bien, hago commit y salvo la operación.
  dbcmd.Transaction.Commit();
  Console.WriteLine("Transacción OK!");
}
catch (DbException dbex)
{
  // Algo salío mal, deshago la transacción.
  dbcmd.Transaction.Rollback();
  Console.WriteLine(dbex.Message);
}

Nota: Aunque en el ejemplo se componen las SQL "a pelo" por brevedad, lo recomendable es usar parámetros con DbParameter.

Tags:

.NET 2.0 | C# 2.0 | ADO.NET

Comentarios

16/09/2007 22:11:19 #

pingback

Pingback from elbruno.com

DbTransaction, transaciones en un Db Factory - vtortola

elbruno.com |

14/11/2007 7:39:51 #

Luis Bragado

Excelente ejemplo para asegurar la informacion; solo para complementar este ejemplo, en SQL Server también se puede manejar un TRY/CATCH y con ello implementar un RollBack en caso de ser necesario.
Un saludo!

Luis Bragado México |

Comentarios no permitidos