transaction management example driven annotation and java hibernate spring transactional

java - management - spring transaction propagation



Ahorro transaccional sin llamar al método de actualización (3)

Tengo un método anotado con @Transactional. Recupero un objeto de mi Oracle DB, cambio un campo y luego regreso del método. Olvidé guardar el objeto, pero descubrí que la base de datos se actualiza de todos modos.

applicationContext

<tx:annotation-driven /> <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory" /> </bean>

mi método

@Transactional public void myMethod(long id) { MyObject myObj = dao.getMstAttributeById(id); myObj.setName("new name"); //dao.update(myObj); }

mi pregunta es ¿por qué MyObject persiste en la base de datos?


Debido a que hibernate detectará automáticamente los cambios realizados a las entidades persistentes y actualizará la base de datos en consecuencia. Este comportamiento está documentado en el capítulo 11 del manual de referencia de hibernación. La parte relevante dice:

Hibernate define y admite los siguientes estados de objeto:

  • Transitorio : un objeto es transitorio si acaba de crear una instancia con el nuevo operador y no está asociado con una Sesión de Hibernación. No tiene representación persistente en la base de datos y no se ha asignado ningún valor de identificador. El recolector de basura destruirá instancias transitorias si la aplicación ya no contiene una referencia. Utilice la sesión de Hibernate para hacer que un objeto sea persistente (y deje que Hibernate se encargue de las declaraciones de SQL que se deben ejecutar para esta transición).

  • Persistente : una instancia persistente tiene una representación en la base de datos y un valor de identificador. Puede haber sido guardado o cargado, sin embargo, es por definición en el ámbito de una sesión. Hibernate detectará cualquier cambio realizado en un objeto en estado persistente y sincronizará el estado con la base de datos cuando la unidad de trabajo finalice. Los desarrolladores no ejecutan sentencias manuales de ACTUALIZACIÓN o DELETA cuando un objeto debe convertirse en transitorio.

  • Independiente : una instancia separada es un objeto persistente, pero su sesión se ha cerrado. La referencia al objeto sigue siendo válida, por supuesto, y la instancia separada puede incluso modificarse en este estado. Una instancia separada se puede volver a conectar a una nueva sesión en un momento posterior, lo que hace (y todas las modificaciones) persistentes de nuevo. Esta característica habilita un modelo de programación para unidades de trabajo de larga ejecución que requieren tiempo de reflexión del usuario. Las llamamos transacciones de aplicaciones, es decir, una unidad de trabajo desde el punto de vista del usuario.


Descubrí que evitar las actualizaciones automáticas en la base de datos es un proceso de dos pasos.

Paso I:

getSession().setFlushMode(FlushMode.MANUAL) // [FlushMode.NEVER is depracated in 4.x]

Paso II:

getSession().clear(); //This will actually discard all changes


Si está utilizando un JPA, entonces la especificación dice que si su Entidad está en estado administrado (y esto es lo que hace al obtener los datos del DAO dentro de una transacción activa), todos los cambios realizados se reflejarán en el base de datos durante la transacción confirmada .

Entonces, en otras palabras, en realidad no importa si se invoca la operación de actualización o no porque la confirmación de la transacción arrojará los cambios a la base de datos.