post icon

Manejar Transacciones en la Base de Datos desde C# .Net y Visual Basic .Net

El concepto de transacción de bases de datos no es para nada nuevo, pero eso no significa que no fuera a ser válido aún, de hecho sigue siendo tan vital como cuando tuvo origen. Tampoco es un concepto dificil de comprender, pero no lo voy a explicar detalladamente, para ello les dejo los enlaces que explican en cristiano su siginificado.

Wiki: http://es.wikipedia.org/wiki/Transacción_(base_de_datos)

Wapedia: http://wapedia.mobi/es/Transacción_(informática)

El código que expondré genéricamente debe funcionar en cualquier SGDB decente, aunque para el ejemplo práctico utilizaré SQL Server. Es un poco precario el Contexto de mi ejemplo, ya que contendrá sólo 2 tablas (no normalizadas) una de cliente y otra de cuenta corriente, simularemos un proceso de transferencia bancaria, en el cual el cliente 1 le transfiere 40000 $ al cliente 2, y bajo ningún caso el dinero a transferir tiene que desaparecer o aparecer independientemente. Tomen en cuenta que no creares las entidades Transacción ni otras que serían de vital importancia si fuera un sistema real, es a modo de entendimiento de la implementación.

El script de la estructura de las tablas es la siguiente:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
CREATE TABLE [dbo].[Cliente](
	[Codigo] [int] IDENTITY(1,1) NOT NULL,
	[Nombre] [varchar](50) NOT NULL,
	[Apellido] [varchar](50) NOT NULL,
	[DocumentoNro] [varchar](50) NOT NULL,
	[Direccion] [varchar](50) NULL,
	[Telefono] [varchar](50) NULL,
	[Email] [varchar](50) NULL,
	[FechaNacimiento] [date] NOT NULL,
 CONSTRAINT [PK_Persona] PRIMARY KEY CLUSTERED
(
	[Codigo] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]
 
GO
CREATE TABLE [dbo].[CtaCte](
	[NroCuenta] [int] NOT NULL,
	[CodCliente] [int] NOT NULL,
	[Saldo] [money] NOT NULL,
 CONSTRAINT [PK_CtaCte] PRIMARY KEY CLUSTERED
(
	[NroCuenta] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]
 
GO
 
ALTER TABLE [dbo].[CtaCte]  WITH CHECK ADD  CONSTRAINT [FK_CtaCte_Cliente] FOREIGN KEY([CodCliente])
REFERENCES [dbo].[Cliente] ([Codigo])
GO
 
ALTER TABLE [dbo].[CtaCte] CHECK CONSTRAINT [FK_CtaCte_Cliente]
GO
 
ALTER TABLE [dbo].[CtaCte] ADD  CONSTRAINT [DF_CtaCte_Saldo]  DEFAULT ((0)) FOR [Saldo]
GO

Ahora veremos un codigo que se conecte a esta BD y realice la transacción, irán uno bajo otro en VB y C# .Net :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
        ' instancia de la conexion
        Dim conn As SqlClient.SqlConnection = New SqlClient.SqlConnection("Data Source=127.0.0.1;Initial Catalog=DevTroce;User Id=sa;Password=******")
        ' objeto transaccional
        Dim tran As SqlClient.SqlTransaction = Nothing
        ' string para transaccion
        Dim strSQL As String = "Update CtaCte set Saldo = Saldo - 40000 where NroCuenta = 100002"
        ' objeto command para ejecucion del query
        Dim command As SqlClient.SqlCommand = New SqlClient.SqlCommand
        ' seteo de atributos del command
        With command
            .Connection = conn
            .CommandType = CommandType.Text
            .CommandTimeout = 0
            .CommandText = strSQL
        End With
 
        Try
            ' abrir conexion
            If conn.State <> ConnectionState.Open Then
                conn.Open()
            End If
            ' comenzamos la transaccion
            tran = conn.BeginTransaction()
            ' asignamos transaccion al command
            command.Transaction = tran
            ' ejecutamos la resta de la transferencia
            command.ExecuteNonQuery()
            ' preparamos la suma del dinero a la otra cuenta
            strSQL = "Update CtaCte set Saldo = Saldo + 40000 where NroCuenta = 100001"
            ' reasignamos es string sql al command
            command.CommandText = strSQL
            ' ejecutamos la suma
            command.ExecuteNonQuery()
            ' si todo salio bien commiteamos los cambios
            tran.Commit()
            ' Emitimos el aviso exitoso
            MessageBox.Show("> Transaccion Exitosa :D")
        Catch ex As Exception
            ' si algo fallo deshacemos todo
            tran.Rollback()
            ' mostramos el mensaje de error
            MessageBox.Show(ex.Message)
        Finally
            ' cerramos la conexion
            If conn.State <> ConnectionState.Closed Then
                conn.Close()
            End If
            ' destruimos la conexion
            conn.Dispose()
        End Try
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
            // instancia de la conexion
            SqlConnection conn = new SqlConnection("Data Source=127.0.0.1;Initial Catalog=DevTroce;User Id=sa;Password=******");
            // objeto transaccional
            SqlTransaction tran = null;
            // string para transaccion
            string strSQL = "Update CtaCte set Saldo = Saldo + 40000 where NroCuenta = 100002";
            // objeto command para ejecucion del query
            SqlCommand command = new SqlCommand();
            // seteo de atributos del command
            command.Connection = conn;
            command.CommandType = CommandType.Text;
            command.CommandTimeout = 0;
            command.CommandText = strSQL;
 
            try
            {
                // abrir la conexion
                if (conn.State != ConnectionState.Open)
                    conn.Open();
                // comenzamos la transaccion
                tran = conn.BeginTransaction();
                // asignamos transaccion al command
                command.Transaction = tran;
                // ejecutamos la suma de la transferencia
                command.ExecuteNonQuery();
                // preparamos la resta del dinero a la otra cuenta
                strSQL = "Update CtaCte set Saldo = Saldo - 40000 where NroCuenta = 100001";
                // reasignamos el string sql al command
                command.CommandText = strSQL;
                // ejecutamos la resta
                command.ExecuteNonQuery();
                // si todo salio bien commiteamos los cambios
                tran.Commit();
                // emitimos el aviso exitoso
                MessageBox.Show("> Transaccion Exitosa :D");
            }
            catch (Exception ex)
            {
                // si algo fallo deshacemos todo
                tran.Rollback();
                // mostramos el mensaje del error
                MessageBox.Show(ex.Message);
            }
            finally
            {
                // cerramos la conexion
                if (conn.State != ConnectionState.Closed)
                    conn.Close();
                // destruimos la conexion
                conn.Dispose();
            }

Comentarios desde Facebook:

  1. avatar
    Joaquín Bresan ARGENTINA Mozilla Firefox Windows
    2 marzo 2014 at 00:27 #

    Gran aporte amigo. Muchas Gracias¡¡¡

  2. avatar
    Mark Mozilla Firefox Windows
    26 febrero 2014 at 14:29 #

    Good!

  3. avatar
    antonio MEXICO Google Chrome Windows
    16 diciembre 2013 at 20:39 #

    necesito como hacer las transacciones de mis tablas medicamento, entrada de medicamento y salida de medicamento xfas necesito hayuda…..

  4. avatar
    Irene NETHERLANDS Mozilla Firefox Windows
    17 febrero 2011 at 07:40 #

    Muy interesante artículo!

Responder