problema transacción oracle
Publicado por jairo1981 (1 intervención) el 06/08/2007 12:08:05
Hola a todos estoy trabajando en un proyecto con una base de datos oracle , tengo que realizar una migración de una base de datos access a una base de datos oracle , esto lo realizo por medio de una transaccción , el problema es que a pesar de realizar el commit de la transacción nunca guarda los cambios realizados . Mi código es el siguiente :
Public Shared Sub RealizaCargaInicialYMigracion(ByVal usuariosDt As DataTable, _
ByVal cajaDt As DataTable, _
ByVal cajaDotacionDt As DataTable, _
ByVal cajaDtosDotacionDt As DataTable, _
ByVal campusDt As DataTable, _
ByVal centrosDt As DataTable, _
ByVal comentariosJustificacionDt As DataTable, _
ByVal conceptoDotacionDt As DataTable, _
ByVal conceptoDtoDt As DataTable, _
ByVal historicoCajeroDt As DataTable, _
ByVal historicoCuentaDt As DataTable, _
ByVal justificadoDt As DataTable, _
ByVal libradoDt As DataTable)
Dim conexion As OracleConnection = Nothing
Dim transaccion As OracleTransaction = Nothing
Try
' Abre la conexion
conexion = New OracleConnection(CadenaConexionBD)
conexion.Open()
' Inicia la transaccion
transaccion = conexion.BeginTransaction()
' Inicializa las tablas y las secuencias
InicializaTablasYSecuencias(transaccion)
' Carga los datos propios de la aplicacion en Oracle y NET
CargaDatosAplicacion(transaccion)
' Actualiza en Oracle los datos comunes en ambas bases
ActualizaDatosCampus(campusDt, transaccion)
ActualizaDatosCentros(centrosDt, transaccion)
ActualizaDatosEntidades(cajaDt, historicoCuentaDt, transaccion)
ActualizaDatosOficinas(cajaDt, historicoCuentaDt, transaccion)
' Importa de las tablas de Access a las de Oracle
ImportarCajas(cajaDt, transaccion)
ImportarCuentas(cajaDt, historicoCuentaDt, transaccion)
ImportarCargos(cajaDt, historicoCajeroDt, transaccion)
ImportarConceptosDotaciones(conceptoDotacionDt, conceptoDtoDt, transaccion)
ImportarDotaciones(cajaDotacionDt, cajaDtosDotacionDt, transaccion)
ImportarLibrados(libradoDt, transaccion)
ImportarJustificados(justificadoDt, comentariosJustificacionDt, transaccion)
' Hace el commit de la transaccion(confirma)
transaccion.Commit()
Catch ex As Exception
transaccion.Rollback() ' Deshace la parte de la transaccion ya ejecutada nunca lo hace
GestionaExcepcion(ex)
Finally
conexion.Close() ' Cierra la conexion
End Try
End Sub
Las funciones a las que llamo son las siguientes:
Private Shared Sub ImportarCajas(ByVal cajasAccessDt As DataTable, ByVal transaccion As OracleTransaction)
Dim n As Integer = 0
LogImportacion("-->Cajas ")
For Each c As DataRow In cajasAccessDt.Rows()
Try
Dim spParam(11) As OracleParameter
Dim f As Object
Dim obsrv As Object = Convert.DBNull
spParam(0) = New OracleParameter("retorno", OracleType.Number)
spParam(0).Direction = ParameterDirection.ReturnValue
spParam(1) = New OracleParameter("codCaja", c("CAJA"))
' El centro hay que calcularlo en funcion del campus
f = Convert.DBNull
If Not c("CAMPUS") Is Convert.DBNull Then
Dim dosDigitosCod As String = c("campus").Substring(1, 2)
f = "9" & dosDigitosCod
End If
spParam(2) = New OracleParameter("codCentro", f)
If Not c("NOMCAJA") Is Convert.DBNull Then c("NOMCAJA") = c("NOMCAJA").ToUpper()
spParam(3) = New OracleParameter("nombre", c("NOMCAJA"))
spParam(4) = New OracleParameter("funcional", c("FUNCIONAL"))
If Not c("DIRECC") Is Convert.DBNull Then c("DIRECC") = c("DIRECC").ToUpper()
spParam(5) = New OracleParameter("dir", c("DIRECC"))
If Not c("LOCALID") Is Convert.DBNull Then c("LOCALID") = c("LOCALID").ToUpper()
spParam(6) = New OracleParameter("loc", c("LOCALID"))
If Not c("TELEFONO") Is Convert.DBNull AndAlso c("TELEFONO").Length > 15 Then
obsrv = "Teléfono:" & vbCrLf & c("TELEFONO") & vbCrLf
spParam(7) = New OracleParameter("tlf", c("TELEFONO").Substring(0, 15))
Else
spParam(7) = New OracleParameter("tlf", c("TELEFONO"))
End If
If Not c("FAX") Is Convert.DBNull AndAlso c("FAX").Length > 15 Then
obsrv = obsrv & "Fax:" & vbCrLf & c("FAX")
End If
Dim fax As Object = Convert.DBNull
Dim mail As Object = Convert.DBNull
DivideFaxMail(c("FAX"), fax, mail)
spParam(8) = New OracleParameter("fax", fax)
spParam(9) = New OracleParameter("mail", mail)
spParam(10) = New OracleParameter("observaciones", obsrv)
f = Convert.DBNull
If Not c("FECHCAJ") Is Convert.DBNull Then
f = c("FECHCAJ").ToShortDateString
End If
spParam(11) = New OracleParameter("fechaCreacion", f)
OracleHelper.ExecuteNonQuery(transaccion, SP_INSERTACAJA, spParam)
InterpretaResultadoBD(spParam(0).Value)
Catch ex As AccesoDatosException
n += 1
LogImportacion(" Nº : " & c("CAJA") & " -> " & ex.Message)
End Try
Next
LogImportacion("Nº Cajas Importadas: " & cajasAccessDt.Rows.Count & "(" & n & " Sin importar)" & vbCrLf)
End Sub
En OracleHelper.ExecuteNonQuery(transaccion, SP_INSERTACAJA, spParam) a veces surge un error xq no son del todo iguales las bases de datos entonces en access hay campos NULL que tienen que ser NOT NULL en oracle , se capturari el error y se mostraria en un log continuando la transacción (hay insert dentro de los procedimientos almacenados que fallan al faltar datos datos necesarios).
¿QUIZÁ EN AL FALLAR UN INSERT SE DESHARÁ LA TRANSACCIÓN Y LOS DATOS QUE SI HAN SIDO VALIDOS NO SE GRABARÁN?
¿AUNQUE SI FUERA ASI DEBERÍA DAR ERROR EN EL COMMIT?
POR CIERTO FUNCIONA HACIENDO COMMIT DENTRO DE OS PROCEDIMIENTOS ALAMACENADOS , PERO HACIENDOLO ASÍ CREO QUE NO TIENE NINGÚN SENTIDO UTILIZAR UNA TRANSACCIÓN.
SI TENEIS ALGUNA IDEA SE AGRADECE .
Public Shared Sub RealizaCargaInicialYMigracion(ByVal usuariosDt As DataTable, _
ByVal cajaDt As DataTable, _
ByVal cajaDotacionDt As DataTable, _
ByVal cajaDtosDotacionDt As DataTable, _
ByVal campusDt As DataTable, _
ByVal centrosDt As DataTable, _
ByVal comentariosJustificacionDt As DataTable, _
ByVal conceptoDotacionDt As DataTable, _
ByVal conceptoDtoDt As DataTable, _
ByVal historicoCajeroDt As DataTable, _
ByVal historicoCuentaDt As DataTable, _
ByVal justificadoDt As DataTable, _
ByVal libradoDt As DataTable)
Dim conexion As OracleConnection = Nothing
Dim transaccion As OracleTransaction = Nothing
Try
' Abre la conexion
conexion = New OracleConnection(CadenaConexionBD)
conexion.Open()
' Inicia la transaccion
transaccion = conexion.BeginTransaction()
' Inicializa las tablas y las secuencias
InicializaTablasYSecuencias(transaccion)
' Carga los datos propios de la aplicacion en Oracle y NET
CargaDatosAplicacion(transaccion)
' Actualiza en Oracle los datos comunes en ambas bases
ActualizaDatosCampus(campusDt, transaccion)
ActualizaDatosCentros(centrosDt, transaccion)
ActualizaDatosEntidades(cajaDt, historicoCuentaDt, transaccion)
ActualizaDatosOficinas(cajaDt, historicoCuentaDt, transaccion)
' Importa de las tablas de Access a las de Oracle
ImportarCajas(cajaDt, transaccion)
ImportarCuentas(cajaDt, historicoCuentaDt, transaccion)
ImportarCargos(cajaDt, historicoCajeroDt, transaccion)
ImportarConceptosDotaciones(conceptoDotacionDt, conceptoDtoDt, transaccion)
ImportarDotaciones(cajaDotacionDt, cajaDtosDotacionDt, transaccion)
ImportarLibrados(libradoDt, transaccion)
ImportarJustificados(justificadoDt, comentariosJustificacionDt, transaccion)
' Hace el commit de la transaccion(confirma)
transaccion.Commit()
Catch ex As Exception
transaccion.Rollback() ' Deshace la parte de la transaccion ya ejecutada nunca lo hace
GestionaExcepcion(ex)
Finally
conexion.Close() ' Cierra la conexion
End Try
End Sub
Las funciones a las que llamo son las siguientes:
Private Shared Sub ImportarCajas(ByVal cajasAccessDt As DataTable, ByVal transaccion As OracleTransaction)
Dim n As Integer = 0
LogImportacion("-->Cajas ")
For Each c As DataRow In cajasAccessDt.Rows()
Try
Dim spParam(11) As OracleParameter
Dim f As Object
Dim obsrv As Object = Convert.DBNull
spParam(0) = New OracleParameter("retorno", OracleType.Number)
spParam(0).Direction = ParameterDirection.ReturnValue
spParam(1) = New OracleParameter("codCaja", c("CAJA"))
' El centro hay que calcularlo en funcion del campus
f = Convert.DBNull
If Not c("CAMPUS") Is Convert.DBNull Then
Dim dosDigitosCod As String = c("campus").Substring(1, 2)
f = "9" & dosDigitosCod
End If
spParam(2) = New OracleParameter("codCentro", f)
If Not c("NOMCAJA") Is Convert.DBNull Then c("NOMCAJA") = c("NOMCAJA").ToUpper()
spParam(3) = New OracleParameter("nombre", c("NOMCAJA"))
spParam(4) = New OracleParameter("funcional", c("FUNCIONAL"))
If Not c("DIRECC") Is Convert.DBNull Then c("DIRECC") = c("DIRECC").ToUpper()
spParam(5) = New OracleParameter("dir", c("DIRECC"))
If Not c("LOCALID") Is Convert.DBNull Then c("LOCALID") = c("LOCALID").ToUpper()
spParam(6) = New OracleParameter("loc", c("LOCALID"))
If Not c("TELEFONO") Is Convert.DBNull AndAlso c("TELEFONO").Length > 15 Then
obsrv = "Teléfono:" & vbCrLf & c("TELEFONO") & vbCrLf
spParam(7) = New OracleParameter("tlf", c("TELEFONO").Substring(0, 15))
Else
spParam(7) = New OracleParameter("tlf", c("TELEFONO"))
End If
If Not c("FAX") Is Convert.DBNull AndAlso c("FAX").Length > 15 Then
obsrv = obsrv & "Fax:" & vbCrLf & c("FAX")
End If
Dim fax As Object = Convert.DBNull
Dim mail As Object = Convert.DBNull
DivideFaxMail(c("FAX"), fax, mail)
spParam(8) = New OracleParameter("fax", fax)
spParam(9) = New OracleParameter("mail", mail)
spParam(10) = New OracleParameter("observaciones", obsrv)
f = Convert.DBNull
If Not c("FECHCAJ") Is Convert.DBNull Then
f = c("FECHCAJ").ToShortDateString
End If
spParam(11) = New OracleParameter("fechaCreacion", f)
OracleHelper.ExecuteNonQuery(transaccion, SP_INSERTACAJA, spParam)
InterpretaResultadoBD(spParam(0).Value)
Catch ex As AccesoDatosException
n += 1
LogImportacion(" Nº : " & c("CAJA") & " -> " & ex.Message)
End Try
Next
LogImportacion("Nº Cajas Importadas: " & cajasAccessDt.Rows.Count & "(" & n & " Sin importar)" & vbCrLf)
End Sub
En OracleHelper.ExecuteNonQuery(transaccion, SP_INSERTACAJA, spParam) a veces surge un error xq no son del todo iguales las bases de datos entonces en access hay campos NULL que tienen que ser NOT NULL en oracle , se capturari el error y se mostraria en un log continuando la transacción (hay insert dentro de los procedimientos almacenados que fallan al faltar datos datos necesarios).
¿QUIZÁ EN AL FALLAR UN INSERT SE DESHARÁ LA TRANSACCIÓN Y LOS DATOS QUE SI HAN SIDO VALIDOS NO SE GRABARÁN?
¿AUNQUE SI FUERA ASI DEBERÍA DAR ERROR EN EL COMMIT?
POR CIERTO FUNCIONA HACIENDO COMMIT DENTRO DE OS PROCEDIMIENTOS ALAMACENADOS , PERO HACIENDOLO ASÍ CREO QUE NO TIENE NINGÚN SENTIDO UTILIZAR UNA TRANSACCIÓN.
SI TENEIS ALGUNA IDEA SE AGRADECE .
Valora esta pregunta


0