duda SimpleJdbctemplate con transction Manager
Hola a todos, mi duda es la sigueinte tengo una operacion de negocio que inserta en una cabecera y 5 detalles, la cuestion es qu si falla la insercion de detalles debo hacer rollback a todas las insercciones anteriores, he tratado de configurar el tranasaction manager de spring y al parecer todo esta bien pero cuando obligo a la operacion a lanzar una excepcion en uno de los detalles no le hacer rollback a nada, anexo mi codigo de configuracion para saber si estoy haciendo algo mal o si me falta algo de antemano gracias por su valiosa atencion
APP Context
.
DAO
.
esta es la inserccion del detalle como se ve le estoy mandando un null al id para que lance la excepcion y pro lo consiguiente deberia de ahcer rollback a la cabecera. si alguien me puede ilustrar en que estoy haciendo mal de antemano se los agradezco
.
- Inicie sesión o regístrese para enviar comentarios
@Transactional
Si usas
, no veo por qué necesitas lo de aop:config.
Todo lo veo bien... excepto que estás cachando DataAccessException.
Para que eso funcione necesitas lo siguiente:
Configurar lo de annotation-driven, indicando una de las dos opciones:
1. Configurar Spring para que tus proxies los haga con CGLIB, creando subclases para envolver TODOS los métodos
2. (más fácil, y la opción default) crear interfaces con los métodos que van a ser transaccionales, y que tus componentes implementen esas interfaces.
Ejemplo:
Eso lo tienes (casi) bien. Y en tu XML va algo así:
Ahí nomás vi que te sobra lo de aop:config pero tal vez es para otra cosa, no sé.
Lo más importante: NO CACHES las excepciones de tiempo de ejecución! si lo haces pues el interceptor no se puede dar cuenta y por eso no da rollback. Si vas a manejar las excepciones entonces TU tienes que manejar tus transacciones. Necesitas más bien algo así:
La documentación de todo este rollo de
y annotation-driven dice que la manera en que funciona es que se abren transacciones para los métodos anotados; si terminan bien su ejecución se hace commit, pero si se arroja cualquier RuntimeException entonces se da rollback. No hay rollback para excepciones declaradas (tu método las debe manejar todas, o arrojar RuntimeException que envuelva una excepción declarada). A fin de cuentas lo que hace es crear un proxy dinámico que envuelva tu componente y hace algo así:
Por lo tanto, obviamente si cachas internamente DataAccessException, pues el método externo nunca se da cuenta y se da commit.
GRacias!!!
ok Pues si hare lo del proxy por default, entoces solo necesito configurar mis clases y en ellas debo de poner un throws SQL Exception?? o solo lo debo dejar sin ningu throws?, si en mi Buissne Object primero ejecuto la inserccion de la cabecera y despues las demas inserciones si alguna de las otras inserciones falla se hara el rollback incluso de la cabecera?
y lo de AOP
dado q nunca he usado el transaction manager fui viendo implementaciones y me encontre una muy parecida a la q yo necesitaba pero no funcionaba asi q pro eso esta eso de AOP pero no lo necesito solo fue un ejemplo fallido
SQLException
SQLException es una excepción declarada, no de tiempo de ejecución. Tus métodos anotados con @Transactional deben manejar ese caso (pero si estás usando JdbcTemplate no veo por qué vas a declarar que arrojas eso).
gracias
Ok, ya cambie mi implementaciion pero no le da rollback a la cabecera, si falla algo en la inserccion de los detalles
metodo del DAO
appcontext
BO
mmmm
pues por como se ve, debería funcionar... lee bien la documentación porque tal vez sea un tema de que estás poniéndole un DataSourceTransactionManager a un DataSource del contenedor (porque lo obtienes por JNDI) y creo que en esos casos debes usar también un transactionManager del contenedor (generalmente si el contenedor maneja dataSources, tiene transactionManagers de JTA).
Ok
Lo revisare esto corre bajo un Glasfish 3.1, pero no tengo configurado ningun JTA en el contenedor aun asi tendria que ponerle un transarciton Manager de JTA?
no
El JtaTransactionManager de Spring es una especie de proxy para usar el manejador de transacciones de JTA del contenedor.
Para probar si es el DataSource, sustitúyelo por uno propio (puedes usar un BasicDataSource de apache DBCP, solamente necesitas agregar dos dependencias a tu proyecto, commons-pool y commons-dbcp, y son en runtime, no hay que recompilar nada). Si con un DataSource propio (creado dentro de tu appcontext) todo funciona OK, entonces la bronca es con el dataSource JNDI.
Que tú no hayas configurado JTA en el contenedor no quiere decir que ya venga por default... otra cosa, el driver JDBC que usas para tu base de datos de JDBC4? Porque creo que tiene que ser JDBC4 o cuando menos JDBC3 (los docs de Spring indican todo eso).
ammm
oks, uso oracle y es ojdbc6.jar
revisa
No sé qué sea eso de ojdbc6.jar pero no existe JDBC tipo 6, solamente hay tipos 1 a 4.
okas
Pues segun ORACLE es la ultima version de su JAR De JDBC
Es la version del driver para Oracle 11.
Es un driver tipo 4 y soporta JDBC 4.0. Este driver de Oracle incluye un DataSource (oracle.jdbc.pool.OracleDataSource).