Você está na página 1de 6

Introducción:

Las transacciones es una forma de controlar si la actualización de datos en una base de datos se deben
aceptar (normalmente si todo ha ido bien) o se deben descartar (si se produce un error), esto nos
asegura que esa actualización de datos se haga solamente si todo ha ido como teníamos previsto.

¿Cuándo usar las transacciones?

Las transacciones tienen sentido si vamos a realizar varias tareas de actualización (ya sea realizando
tareas de actualización, inserción o eliminación), por ejemplo si intervienen varias tablas, ya que
podemos actualizar los datos de una tabla y al intentar actualizar otra, es cuando se produce un error,
en este caso, podemos deshacer los cambios realizados en la primera tabla y cancelar toda la operación,
de esta forma nos aseguramos que no queden datos "colgados" y que sólo tienen sentido si se realiza el
proceso completo.
Aunque podemos usarlas siempre, para asegurarnos de que no habrá problemas, pero si solo vamos a
leer datos, pues como que no tiene ninguna utilidad.

¿Cómo hacer una transacción?

Las transacciones se pueden hacer por código o directamente en el servidor (mediante procedimientos
almacenados), aquí veremos solo cómo hacer esas transacciones por código y las que se conocen como
transacciones locales, es decir, no transacciones distribuidas, para ese tipo de transacciones te
recomiendo que veas las clases de System.Transactions, ya que aquí solo veremos las que podemos
hacer por medio del objeto Transaction que devuelve el método BeginTransaction del objeto
Connection (en estos ejemplos usaremos bases de datos de SQL Server 2005 Express).

Una vez que tenemos un objeto del tipo Transaction, debemos asignarlo a la propiedad del mismo
nombre de cada uno de los comandos que intervendrán en la transacción, si no lo asignamos tendremos
un bonito error, así que... una vez que usemos el método BeginTransaction del objeto Connection,
debemos asignar esa transacción a cada comando que vayamos a usar.

Aceptar y/o cancelar una transacción

Una vez que tenemos todo bajo la "tutela" de un objeto Transaction, podemos aceptar todo los cambios
realizados llamando al método Commit. Y si algo ha salido mal, o simplemente queremos cancelar todo
lo que se ha hecho, llamaremos al método Rollback de ese objeto y como si nada hubiera pasado,
vamos como se suele decir: aquí paz y después gloria.

Y esto es todo lo que tienes que saber sobre las transacciones, ves como no era tan complicado.

¿Cómo dices?
¿No te has enterado?
Pero si está claro, a ver... primero abres la conexión, creas el objeto Transaction mediante el método
BeginTransaction de esa conexión, creas los comandos, le asignas a la propiedad Transaction de cada
comando ese objeto que te habrá devuelto el método BeginTransaction (y que habrás guardado en una
variable del tipo Transaction), usas esos comandos (que también tendrán que estar relacionados con el
objeto Connection), y si todo ha ido bien, llamas al método Commit del objeto Transaction, y en caso de
que haya algún error o quieras cancelar, simplemente llamas al método Rollback de ese mismo objeto
Transaction, y ya está.
¿Cómo? ¿Que quieres un ejemplo? Y además lo quieres en Visual Basic y en C#, si es que... bueno... vale.

Un ejemplo que usa todo lo comentado (en Visual Basic y C#)

En este ejemplo usaremos un comando INSERT a una tabla y todo el proceso lo incluiremos en una
transacción.
Se supone que estás usando la versión 2005 ó 2008 de los lenguajes, vamos que estamos usando las
clases incluidas con la versión 2.0 (o superior) de .NET Framework.

Paso 1, Crear el objeto SqlConnetion.


En este ejemplo, accedo a una base de datos llamada Prueba que está en el servidor local y en la
instancia SQLEXPRESS (si vas a usar otra base de datos, tendrás que cambiar los valores de la cadena de
conexión).
La conexión la creo en un bloque Using para que se cierre adecuadamente (y se liberen los recursos) si
se produce un error no controlado.

' La cadena de conexión


Dim csb As New SqlConnectionStringBuilder
With csb
' El servidor al que nos conectamos
.DataSource = "(local)\SQLEXPRESS"
' La base de datos que vamos a usar
.InitialCatalog = "prueba"
' Usamos la seguridad integrada
.IntegratedSecurity = True
End With

' Creamos la conexión


' la ponemos dentro de Using para asegurarnos de que se cierre si hay errores
Using con As New SqlConnection(csb.ConnectionString)
' Abrimos la conexión
con.Open()

// La cadena de conexión
SqlConnectionStringBuilder csb = new SqlConnectionStringBuilder();
// El servidor al que nos conectamos
csb.DataSource = @"(local)\SQLEXPRESS";
// La base de datos que vamos a usar
csb.InitialCatalog = "prueba";
// Usamos la seguridad integrada
csb.IntegratedSecurity = true;
// Creamos la conexión
// la ponemos dentro de Using para asegurarnos de que se cierre si hay errores
using(SqlConnection con = new SqlConnection(csb.ConnectionString))
{
// Abrimos la conexión
con.Open();

Paso 2. Crear el objeto Transaction.


Simplemente asignamos a una variable del tipo SqlTransaction el valor devuelto por el método
BeginTransaction del objeto que tiene la conexión.

' Creamos el objeto Transaction


Dim tran As SqlTransaction = con.BeginTransaction

// Creamos el objeto Transaction


SqlTransaction tran = con.BeginTransaction();

Paso 3. Creamos el objeto SqlCommand con el comando INSERT INTO adecuado (también podríamos
llamar a un procedimiento almacenado). Se utilizan parámetros, ya que así es un poco más seguro y
evitamos las temidas SQL-Injection o dicho de forma llana, evitamos que no las cuelen... o casi... ;-)))

' Creamos el comando de inserción con parámetros


' La tabla que usaré se llama Table1
Dim sInsert As String = _
"INSERT INTO Table1 " & _
"(Nombre, Correo, Fecha) " & _
"VALUES (@Nombre, @Correo, @Fecha)"

' Creamos el objeto SqlCommand y asignamos los datos


' a los parámetros
Dim cmd As New SqlCommand(sInsert, con)

With cmd
.Parameters.AddWithValue("@Nombre", txtNombre.Text)
.Parameters.AddWithValue("@Correo", txtCorreo.Text)
.Parameters.AddWithValue("@Fecha", txtFecha.Value)
End With

 
// Creamos el comando de inserción con parámetros
// La tabla que usaré se llama Table1
string sInsert =
"INSERT INTO Table1 " +
"(Nombre, Correo, Fecha) " +
"VALUES (@Nombre, @Correo, @Fecha)";

// Creamos el objeto SqlCommand y asignamos los datos


// a los parámetros
SqlCommand cmd = new SqlCommand(sInsert, con);

cmd.Parameters.AddWithValue("@Nombre", txtNombre.Text);
cmd.Parameters.AddWithValue("@Correo", txtCorreo.Text);
cmd.Parameters.AddWithValue("@Fecha", txtFecha.Value);

Paso 4. Asignamos la transacción al método Transaction del comando.


Esto siempre debemos hacerlo en todos los comandos que modifiquen los datos, si no lo asignamos,
recibiremos un error.

' Asignamos la transacción al comando


cmd.Transaction = tran

// Asignamos la transacción al comando


cmd.Transaction = tran;

Paso 5. Ejecutamos el comando.


La llamada al método ExecuteNonQuery lo ponemos dentro de un Try/Catch, de esta forma, si todo va
bien (no se produce error) llamamos al método Commit del objeto Transaction (la variable tran).
Y si se produce algún error deshacemos todo, llamando al método Rollback del objeto Transaction.

' Insertamos los datos


' lo pongo en un Try/Catch para detectar los errores
Try
' Ejecutamos el comando
cmd.ExecuteNonQuery()

' Si llega aquí es que todo fue bien,


' por tanto, llamamos al método Commit
tran.Commit()

txtInfo.Text = "Se han actualizado los datos"


Catch ex As Exception
' Si hay error, desahacemos lo que se haya hecho
tran.Rollback()

txtInfo.Text = "ERROR: " & vbCrLf & ex.Message


End Try

// Insertamos los datos


// lo pongo en un Try/Catch para detectar los errores
try
{
// Ejecutamos el comando
cmd.ExecuteNonQuery();

// Si llega aquí es que todo fue bien,


// por tanto, llamamos al método Commit
tran.Commit();

txtInfo.Text = "Se han actualizado los datos";

}
catch(Exception ex)
{
// Si hay error, desahacemos lo que se haya hecho
tran.Rollback();

txtInfo.Text = "ERROR: \r\n" + ex.Message;


}

Paso 6. Cerramos la conexión.


En realidad no es necesario, ya que al estar dentro de un bloque Using, se cerrará al llamar al método
Dispose del objeto conexión.

' Cerramos la conexión,


' aunque no es necesario ya que al finalizar
' el using se cerrará
con.Close()
End Using

// Cerramos la conexión,
// aunque no es necesario ya que al finalizar
// el using se cerrará
con.Close();
}

Ahora sí que sí... Espero que te sea de utilidad y sepas cómo usar las transacciones, aunque sea de forma
simple.

Nos vemos.
Guillermo

P.S.
Si quieres ver qué cosas debes tener en cuenta si las actualizaciones las haces por medio del modo
desconectado (con un DataAdapter y un DataTable o DataSet), mira esto: Transacciones simples con
ADO.NET usando un DataAdapter.

Espacios de nombres usados en el código de este artículo:

System.Data.SqlClient
System.Data 

Você também pode gostar