Acabo de arreglar un codigo que estaba mas o menos asi::
transaction = connection.BeginTransaction();
try {
try {
//***.... algunas operaciones en la DB aqui...
} finally {
transaction.Commit();
}
}
catch {
transaction.RollBack();
}
Primero que nada, hay un bug ahi, si el codigo de enmedio nos diera una exception, este codigo generaria una nueva exception en la seccion del catch{} porque no podemos hacer rollback a una transaccion que ya se le hizo commit (el mensaje no sera asi de claro, pero eso es lo que quiere decir, la excepcion dice algo como que la operacion no puede ser completada debido al estado actual del objeto), y perderas la informacion de la excepcion original
Segundo, simplemente esta mal!, quita cualquier beneficio que tenias con la transaccion, es como decir:
//*** borrar algunos registros
//*** actualizar algunos registros
//*** alguna operacion que causo una excepcion
//*** finalmente, confirmar lo que halla hecho hasta ahorita
Dejando tus datos en un estado indeterminado (no sabes hasta donde llego tu codigo antes del error) porque confirmaste la operacion hasta donde los errores hallan ocurrido.
pista: siempre usa "using" para cualquier cosa relacionada con la base de datos (connecciones, commandos, transacciones, etc)
update: gracias a Kamikaze por encontrar un bug
4 comments:
Interesante blog. Programo bastante en c# y me gusta este tipo de blogs, llenos de trucos interesantes para aplicar día a día.
¡Ánimo!.
ahi estamos aportando un granito de arena; en ingles hay mucho material, y se que hay muchos desarrolladores hispanos que desafortunadamente (para su suerte) no mastican el lenguaje de Shakespeare (osea el ingles pues)
y pues espero poder contribuir un poco con este blog
oye, pero creo que el bug en realidad está en el orden del try/catch.
¿qué el orden no es try/catch/finally, en lugar de try/finally/catch? (Creo que fue error del post, porque no creo que el compilador te permita un orden distinto.)
Finally se ejecuta siempre (se haya o no levantado una excepción) y si pones ahi el Commit pues no sirve de nada. En cualquier caso, tienes razón. El commit debería en dado caso hacia el final dentro del try, y en dado caso el rollback en el catch.
Mejor aún si especificas el tipo de exception, aunque no hagas nada con ella
// asumiendo SQL Data Provider
try {}
catch (SqlException) {}
catch (ApplicationException){}
// etc.
finally {}
ups, el codigo lo teclee aqui directamente, deberia tener otro block de try..catch afuera de ese try..finally
deja lo arreglo
gracias
Post a Comment