Está en la página 1de 9

Capítulo 5

Gestionando transacciones

Objetivo

Al finalizar el capítulo, el alumno:

 Realiza transacciones locales y distribuidas utilizando ADO.NET y


Entity Framework.

Temas

 Introducción a las transacciones


 Transacciones locales con ADO.NET
 Transacciones distribuidas con System.Transaction
 Transacciones con Entity Framework

Cibertec Perú S.A.C – Visual Studio 2015 Developer – C# (PDS1508)


Gestionando transacciones 42

1. Introducción a las transacciones

Una transacción es una unidad de trabajo que contiene un conjunto de


operaciones; si todas las operaciones son exitosas, entonces, la transacción
termina de completarse, pero si una operación falla, entonces toda la
transacción también lo hará.

Se usan transacciones para asegurar la consistencia e integridad de una base


de datos. Si una transacción es exitosa entonces todas las modificaciones de
datos realizadas durante la transacción se hacen permanentes mediante un
Commit. Si se comete un error durante la transacción, se pueden deshacer las
modificaciones de datos en esa transacción, a través de un Rollback.

El .NET Framework brinda soporte para transacciones locales y transacciones


distribuidas, las cuales se definen de la siguiente manera:

 Transacciones locales. Una transacción local trabaja sobre una única


fuente de datos. Las transacciones locales son controladas por la fuente de
datos, son eficientes y fáciles de manejar.
 Transacciones distribuidas. Una transacción distribuida se realiza sobre
múltiples fuentes de datos. Las transacciones distribuidas permiten
incorporar distintas operaciones, las cuales ocurren en diferentes sistemas,
en una acción atómica que puede ser exitosa o fallar completamente.

Una transacción tiene las siguientes propiedades (ACID):

 Atomicidad. Este término indica que un cambio en el estado de una


transacción se produce totalmente o no se produce. Una transacción es un
conjunto de operaciones, las cuales se ejecutan en su totalidad o
simplemente, no se ejecuta ninguna.

Cibertec Perú S.A.C – Visual Studio 2015 Developer – C# (PDS1508)


Gestionando transacciones 43

 Consistencia. Este término indica que una transacción es una


transformación correcta del estado. Asimismo, asegura que si hay un
cambio en la base de datos, este sea de un estado consistente a otro
estado consistente. Para ello, es necesario que la transacción sea un
programa correcto.
 Aislamiento. Este término indica que aunque las transacciones se ejecuten
simultáneamente, cada transacción percibirá que las otras se ejecutan
antes o después que ella, pero no en paralelo.

 Durabilidad. Este término indica que en cuanto se ejecute


correctamente una transacción (se valida), cambia el estado para
resistir cualquier error y el nuevo estado será persistente en el
tiempo.

Manejando transacciones con SQL Server

A nivel de base de datos, por ejemplo con un MS SQL Server, se pueden


manejar transacciones locales con las instrucciones de Transact-SQL.

 Begin Transaction. Esta instrucción indica al motor de base de datos, que


se está iniciando una transacción, la cual puede estar compuesta por una o
más sentencias SQL.
 Commit Transaction. Esta instrucción debería ejecutarse después de que
todas las sentencias SQL de la transacción se han realizado con éxito.
 Rollback Transaction. Esta instrucción se debe ejecutar si alguna de las
sentencias SQL de la transacción, no se ejecutó correctamente.

Estas instrucciones deben ejecutarse sobre una misma conexión de base de


datos.

Cibertec Perú S.A.C – Visual Studio 2015 Developer – C# (PDS1508)


Gestionando transacciones 44

2. Transacciones locales con ADO.NET

Cada proveedor de datos del .NET Framework ofrece una clase destinada al
tratamiento de transacciones. Esta clase implementa la interface
IDbTransaction, la cual contiene métodos para crear y ejecutar transacciones
sobre una fuente de datos.

Las siguientes son las clases transaccionales presentes en .NET Framework:

 System.Data.SqlClient.SqlTransaction
 System.Data.OleDbClient.OleDbTransaction
 System.Data.Odbc.OdbcTransaction

Cada transacción está asociada a una conexión en particular. Para comenzar


una transacción sobre una conexión, se debe realizar un llamado al método
BeginTransaction, este método está disponible dentro de un objeto del tipo
Connection. El método BeginTransaction devuelve un objeto del tipo
Transaction.

Cibertec Perú S.A.C – Visual Studio 2015 Developer – C# (PDS1508)


Gestionando transacciones 45

Para realizar operaciones dentro de una transacción, se debe configurar la


propiedad Connection de un objeto Command, de tal forma, que haga
referencia que está ejecutando la transacción, al objeto Connection; luego, se
debe establecer el valor de la propiedad Transaction del objeto Command de
tal forma, que haga referencia al objeto Transaction, el cual es generado por el
BeginTransaction.

Si todas las sentencias SQL ejecutadas sobre una misma transacción se


completan con éxito, entonces se debe hacer un llamado al método Commit del
objeto Transaction. Si algún comando falla, entonces se debe hacer un llamado
al método RollBack del objeto Transaction.

Cibertec Perú S.A.C – Visual Studio 2015 Developer – C# (PDS1508)


Gestionando transacciones 46

3. Transacciones distribuidas con System.Transaction

.NET Framework incluye el namespace System.Transactions, el cual


proporciona soporte para transacciones distribuidas, que se ejecutan sobre
administradores de transacciones relacionados a fuentes de datos o colas de
mensajes (Message Queue).

De igual forma, la clase TransactionScope, la cual se encuentra dentro del


namespace System.Transactions, permite crear y administrar transacciones
distribuidas.

Para crear y ejecutar transacciones distribuidas, se debe instanciar un objeto


de la clase TransactionScope y especificar si se desea crear un nuevo contexto
de transacción o enlistar las transacciones en un contexto de transacción ya
existente.

Cibertec Perú S.A.C – Visual Studio 2015 Developer – C# (PDS1508)


Gestionando transacciones 47

4. Transacciones con Entity Framework

En EF se pueden usar también transacciones de manera local y distribuida.

Transacciones en EF de manera local


Para las transacciones locales se puede hacer uso del método
Database.BeginTransaction que se encuentra en el DbContext, este objeto
puede ser configurado con el IsolationLevel que se desee usar. Para confirmar
las operaciones no basta con llamar a SaveChanges sino que tiene que
llamarse al método Commit.

public void ExecuteLocalTransaction(string newCategoryName, string newSubcategoryName) {


using (var context = new AwContext()) {
using (var transaction =
context.Database.BeginTransaction(System.Data.IsolationLevel.RepeatableRead)) {
try {
var newProductCategoryId =
context.Database.SqlQuery<int>(@"INSERT INTO [Production].[ProductCategory]
([Name]) VALUES (@name)
SELECT CAST(SCOPE_IDENTITY() AS INT)", new SqlParameter("name",
newCategoryName)).First();

var newProductSubcategory = new ProductSubcategory {


ProductCategoryID = newProductCategoryId,
Name = newSubcategoryName
};
context.ProductSubcategories.Add(newProductSubcategory);

Cibertec Perú S.A.C – Visual Studio 2015 Developer – C# (PDS1508)


Gestionando transacciones 48

context.SaveChanges();
transaction.Commit();
}
catch (Exception) {
transaction.Rollback();
}
}
}
}

Transacciones en EF de manera distribuida

En EF se soportan transacciones distribuidas también con el objeto


TransactionScope, el cual delimita las operaciones que ejecutaremos como una
sola transacción y si estamos utilizando diferentes fuentes de datos en la
transacción se encargará de escalar esta transacción en inicio local a una
transacción distribuida con el apoyo del MSDTC (Microsoft Distributed
Transaction Coordinator).

public void ExecuteDistributedTransaction(string newCategoryName, string


newSubCategoryName) {
using (var scope = new TransactionScope(TransactionScopeOption.Required)) {
int newProductCategoryId;

using (var conn = AdoConn.GetSqlConnection()) {


conn.Open();
var sqlCommand = new SqlCommand();
sqlCommand.Connection = conn;
sqlCommand.CommandText =
@"INSERT INTO [Production].[ProductCategory]
([Name]) VALUES (@name)
SELECT SCOPE_IDENTITY()";
sqlCommand.Parameters.AddWithValue("name", newCategoryName);
newProductCategoryId = Convert.ToInt32(sqlCommand.ExecuteScalar());
}

using (var dbContext = new AwContext()) {


var newProductSubcategory = new ProductSubcategory {
ProductCategoryID = newProductCategoryId,
Name = newSubCategoryName
};
dbContext.ProductSubcategories.Add(newProductSubcategory);

dbContext.SaveChanges();
}

scope.Complete();
}
}

Cibertec Perú S.A.C – Visual Studio 2015 Developer – C# (PDS1508)


Gestionando transacciones 49

Ejercicio Nº 5

Cibertec Perú S.A.C – Visual Studio 2015 Developer – C# (PDS1508)

También podría gustarte