El problema con mas nivel de detalle La base de datos es Postgres y la tabla es efectivamente transaccional .Utilizo el dirver Npgsql de la misma firma para conectarme a la base de datos, por último utilizo Stored Procedures.La arquitectura que implemento es la orientada a servicio. Capa de datos, Negocio , Servicio,UI. Cada capa la manejo como una librería o proyecto distinta y voy referenciando de una capa a otra entre si (Negocio a datos, servicio a negocio y Ui a servicio). Estoy utilizando TransactionScope como gestor de bloque de transacciones en la Capa de servicio, la cual llama a dos negocios de inserción dentro de la misma transacción y obviamente dentro del mismo servicio.
Tengo una clase mensajes que realiza el control de flujo de errores que contiene tablas con los distintos tipos como Mensajes,Errores,Excepciones y Advertencias, cuyos datos utilizo a la hora de capturar/almacenar todo tipo de mensajes y presentarlos en la Ui
El método "EstaBien" indica que ni la tabla de errores ni excepciones contienen registros por lo tanto puede darse entendida como correcta la transacción por que se supone no hubo ningún inconveniente.
Por ello es que pregunto al final del "try" si no hubo ningún inconveniente, para por dar el "Complete!" del transactionScope. El problema es que en el segundo negocio invocado en el servicio "NegocioInsertarConsumosTelefonicosClaroTodo", existe un error de negocio por el cual grabo una excepción que al preguntar si estaBien saltea el Complete cuestión por la cual el primer negocio de inserción debería descartarse, cosa que no ocurre.
La descripción de servicio. Insertar una tabla de cabecera(primer método invocado) y otra tabla con los detalles de dicha cabecera. Repito la cabecera si inserta sin problemas pero genero un error de negocio en el otro metodo(insertar detalle mas precisamente: NegocioInsertarConsumosTelefonicosClaroTodo) genero un error de negocio(Fila nula de excel), por el cual se saltea el complete del transactionScope, motivo por el cual no debería afectarse la primer tabla(la cabecera). Estas son las capas en resumidas cuentas: Capa Servicio:
Public Shared Function ServicioInsertarConsumosTelefonicosClaroTodo(ByVal tabla As DataTable, ByVal numero As String, ByVal legajo As String, ByVal fechaInicio As Date, ByVal fechaFin As Date) As DataSet
Dim resultado As New DataSet
Try
Using transaccion = New TransactionScope()
If Mensajes.EstaBien(resultado) Then
resultado = NegocioConsumosTelefonicosClaro.NegocioInsertarLot esConsumosTelefonicosClaro(numero, legajo, fechaInicio, fechaFin)
End If
If Mensajes.EstaBien(resultado) Then
resultado = NegocioConsumosTelefonicosClaro.NegocioInsertarCon sumosTelefonicosClaroTodo(tabla, numero, legajo)
End If
If Mensajes.EstaBien(resultado) Then
transaccion.Complete()
Mensajes.InsertarMensaje(resultado, TipoMensaje.mensaje, 0, "El registro se ha insertado correctamente", "El registro se ha insertado correctamente")
End If
End Using
Catch ex As Exception
Mensajes.InsertarMensaje(resultado, TipoMensaje.error, Err.Number, ex.Message, ex.StackTrace)
End Try
Return resultado
End Function Negocios:
Public Shared Function NegocioInsertarConsumosTelefonicosClaroTodo(ByVal tabla As DataTable, ByVal numero As String, ByVal legajo As String) As DataSet
Dim resultado As New DataSet
Dim lote As Double
Dim aire As Double
Dim redFija As Double
Dim total As Double
If Mensajes.EstaBien(resultado) Then
resultado = DatosConsumosTelefonicosClaro.DatosLeerMaximoLote( numero, legajo)
lote = CType(resultado.Tables(TablasSistemaGt.pleo_lotesc onsumostelefonicosclaro.ToString).Rows(0)(0), Double)
If Mensajes.EstaBien(resultado) Then
For Each fila As DataRow In tabla.Rows
If Not IsNumeric(fila("numero")) Or Not IsNumeric(fila("celular")) Or Not IsNumeric(fila("minutos")) Then
Mensajes.InsertarMensaje(resultado, TipoMensaje.error, 0, "No se puede insertar registros,hay filas nulas!", "No se puede insertar registros,hay filas nulas!")
Exit For
End If
Next
If Mensajes.EstaBien(resultado) Then
For Each fila As DataRow In tabla.Rows
aire = CType(Replace(fila("aire").ToString, ".", ","), Double)
redFija = CType(Replace(fila("red fija").ToString, ".", ","), Double)
total = CType(Replace(fila("total").ToString, ".", ","), Double)
resultado = DatosConsumosTelefonicosClaro.DatosInsertarConsumo sTelefonicosClaro(fila("celular").ToString, CType(fila("Fecha"), Date), CType(fila("hora"), Date), fila("destino").ToString, fila("numero").ToString, fila("tipo").ToString, fila("tarifa").ToString, CType(fila("minutos"), Double), aire, redFija, total, lote)
Next
End If
End If
End If
Return resultado
End Function
Public Shared Function NegocioInsertarLotesConsumosTelefonicosClaro(ByVal numero As String, ByVal legajo As String, ByVal fechaInicio As Date, ByVal fechaFin As Date) As DataSet
Dim resultado As New DataSet
Dim fechaInicioAuxiliar As String
Dim fechaFinAuxiliar As String
If String.IsNullOrEmpty(numero) Then
Mensajes.InsertarMensaje(resultado, TipoMensaje.error, 0, "No se puede insertar,el numero no es válido", "No se puede insertar,el numero no es válido")
ElseIf String.IsNullOrEmpty(legajo) Then
Mensajes.InsertarMensaje(resultado, TipoMensaje.error, 0, "No se puede insertar,el legajo no es válido", "No se puede insertar,el legajo no es válido")
Else
resultado = DatosPersonas.DatoLeerPersonas(legajo)
If resultado.Tables(TablasSistemaGt.pleo_personas.ToS tring).Rows.Count <= 0 Then
Mensajes.InsertarMensaje(resultado, TipoMensaje.error, 0, "El legajo es inexistente", "Debe dar el alta del mismo")
Else
resultado = DatosCelulares.DatoLeerCelulares(CType(numero, Double))
If resultado.Tables(TablasSistemaGt.pleo_celulares.To String).Rows.Count <= 0 Then
Mensajes.InsertarMensaje(resultado, TipoMensaje.error, 0, "El celular es inexistente", "De dar el alta del mismo")
Else
fechaInicioAuxiliar = Format(fechaInicio, "yyyy-MM-dd").ToString
fechaFinAuxiliar = Format(fechaFin, "yyyy-MM-dd").ToString
resultado = DatosConsumosTelefonicosClaro.DatosInsertarLotesCo nsumosTelefonicosClaro(numero, legajo, fechaInicioAuxiliar, fechaFinAuxiliar)
End If
End If
End If
Return resultado
End Function |