[Использование: C # 3.5 + SQL Server 2005]
У меня есть некоторый код в бизнес-уровне, который оборачивает в TransactionScope создание заказа и его детали:
DAL.DAL_OrdenDeCompra dalOrdenDeCompra = new GOA.DAL.DAL_OrdenDeCompra();
DAL.DAL_ItemDeUnaOrden dalItemDeUnaOrden = new GOA.DAL.DAL_ItemDeUnaOrden();
using (TransactionScope transaccion = new TransactionScope())
{
//Insertion of the order
orden.Id = dalOrdenDeCompra.InsertarOrdenDeCompra(orden.NumeroOrden, orden.PuntoDeEntregaParaLaOrden.Id, (int)orden.TipoDeCompra, orden.FechaOrden, orden.Observaciones);
foreach (ItemDeUnaOrden item in orden.Items)
{
//Insertion of each one of its items.
dalItemDeUnaOrden.InsertarItemDeUnaOrden(orden.Id, item.CodigoProductoAudifarma, item.CodigoProductoJanssen, item.CodigoEAN13, item.Descripcion, item.CantidadOriginal, item.ValorUnitario);
}
transaccion.Complete();
}
return true;
А вот код DAL, который выполняет вставки:
public int InsertarOrdenDeCompra(string pNumeroOrden, int pPuntoEntregaId, int pTipoDeCompra, DateTime pFechaOrden, string pObservaciones)
{
try
{
DataTable dataTable = new DataTable();
using (SqlConnection conexion = new SqlConnection())
{
using (SqlCommand comando = new SqlCommand())
{
ConnectionStringSettings conString = ConfigurationManager.ConnectionStrings["CSMARTDB"];
conexion.ConnectionString = conString.ConnectionString;
conexion.Open();
comando.Connection = conexion;
comando.CommandType = CommandType.StoredProcedure;
comando.CommandText = "GOA_InsertarOrdenDeCompra";
//...parameters setting
return (int)comando.ExecuteScalar();
...
public int InsertarItemDeUnaOrden(int pOrdenDeCompraId, string pCodigoProductoAudifarma, string pCodigoProductoJanssen, string pCodigoEAN13, string pDescripcion, int pCantidadOriginal, decimal pValorUnitario)
{
try
{
DataTable dataTable = new DataTable();
using (SqlConnection conexion = new SqlConnection())
{
using (SqlCommand comando = new SqlCommand())
{
ConnectionStringSettings conString = ConfigurationManager.ConnectionStrings["CSMARTDB"];
conexion.ConnectionString = conString.ConnectionString;
conexion.Open();
comando.Connection = conexion;
comando.CommandType = CommandType.StoredProcedure;
comando.CommandText = "GOA_InsertarItemDeUnaOrden";
//... parameters setting
return comando.ExecuteNonQuery();
Теперь моя проблема в вставке предметов; когда InsertarItemDeUnaOrden пытается открыть новое соединение, возникает исключение, потому что это приведет к тому, что TransactionScope попытается перейти на MSDTC, который у меня не включен, и я предпочел бы не включать.
Мои сомнения:
- Понимание того, что метод, который запускает транзакцию, находится на бизнес-уровне, и я не хочу там никакого SqlConnection,, могу ли я использовать другой дизайн для доступа к данным, чтобы я мог повторно использовать то же соединение?
- Должен ли я включить MSDTC и забыть об этом?
Спасибо.
РЕДАКТИРОВАТЬ: решение
Я создал новый класс в DAL для хранения транзакций, таких как:
namespace GOA.DAL
{
public class DAL_Management
{
public SqlConnection ConexionTransaccional { get; set; }
public bool TransaccionAbierta { get; set; }
public DAL_Management(bool pIniciarTransaccion)
{
if (pIniciarTransaccion)
{
this.IniciarTransaccion();
}
else
{
TransaccionAbierta = false;
}
}
private void IniciarTransaccion()
{
this.TransaccionAbierta = true;
this.ConexionTransaccional = new SqlConnection();
ConnectionStringSettings conString = ConfigurationManager.ConnectionStrings["CSMARTDB"];
this.ConexionTransaccional.ConnectionString = conString.ConnectionString;
this.ConexionTransaccional.Open();
}
public void FinalizarTransaccion()
{
this.ConexionTransaccional.Close();
this.ConexionTransaccional = null;
this.TransaccionAbierta = false;
}
}
}
Я изменил методы выполнения DAL, чтобы получить параметр этого нового класса, и использую его следующим образом:
public int InsertarItemDeUnaOrden(int pOrdenDeCompraId, string pCodigoProductoAudifarma, string pCodigoProductoJanssen, string pCodigoEAN13, string pDescripcion, int pCantidadOriginal, decimal pValorUnitario, DAL_Management pManejadorDAL)
{
try
{
DataTable dataTable = new DataTable();
using (SqlConnection conexion = new SqlConnection())
{
using (SqlCommand comando = new SqlCommand())
{
if (pManejadorDAL.TransaccionAbierta == true)
{
comando.Connection = pManejadorDAL.ConexionTransaccional;
}
else
{
ConnectionStringSettings conString = ConfigurationManager.ConnectionStrings["CSMARTDB"];
conexion.ConnectionString = conString.ConnectionString;
conexion.Open();
comando.Connection = conexion;
}
comando.CommandType = CommandType.StoredProcedure;
comando.CommandText = "GOA_InsertarItemDeUnaOrden";
И, наконец, изменил вызывающий класс:
DAL.DAL_OrdenDeCompra dalOrdenDeCompra = new GOA.DAL.DAL_OrdenDeCompra();
DAL.DAL_ItemDeUnaOrden dalItemDeUnaOrden = new GOA.DAL.DAL_ItemDeUnaOrden();
using (TransactionScope transaccion = new TransactionScope())
{
DAL.DAL_Management dalManagement = new GOA.DAL.DAL_Management(true);
orden.Id = dalOrdenDeCompra.InsertarOrdenDeCompra(orden.NumeroOrden, orden.PuntoDeEntregaParaLaOrden.Id, (int)orden.TipoDeCompra, orden.FechaOrden, orden.Observaciones, dalManagement);
foreach (ItemDeUnaOrden item in orden.Items)
{
dalItemDeUnaOrden.InsertarItemDeUnaOrden(orden.Id, item.CodigoProductoAudifarma, item.CodigoProductoJanssen, item.CodigoEAN13, item.Descripcion, item.CantidadOriginal, item.ValorUnitario, dalManagement);
}
transaccion.Complete();
}
dalManagement.FinalizarTransaccion();
С этими изменениями я вставляю заказы и позиции без включения MSDTC.