Spring AOP integra el soporte AOP en la infraestructura misma de Spring, permitiéndonos declarar la transaccionalidad de los servicios en el mismo XML de configuración de nuestros beans.
Típicamente, en Spring 1.1.1, definimos una plantilla para nuestras transacciones:
<bean id="daoTxProxyTemplate" abstract="true"en la cual está especificado el transactionManager que utilizaremos, y una serie de patterns de nombres de métodos, sobre los cuales definiremos que tipo de transacción es requerida para los métodos que se ajusten a ese pattern.
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager"><ref bean="transactionManager"/></property>
<property name="transactionAttributes">
<props>
<prop key="save*">PROPAGATION_REQUIRED</prop>
<prop key="remove*">PROPAGATION_REQUIRED</prop>
<prop key="update*">PROPAGATION_REQUIRED</prop>
<prop key="*">PROPAGATION_REQUIRED,readOnly</prop>
</props>
</property>
</bean>
Luego solo queda comenzar a definir nuestros servicios, con la implementación como inner bean:
<bean id="itemManager" parent="daoTxProxyTemplate">Asi, ante cada llamada al método saveItem de la clase itemManagerImpl (definida en el bean itemManager), Spring creará una transacción (o reutilizará una existente) antes de la llamada, y hará el commit luego de ella.
<property name="target">
<bean class="com.example.services.itemManagerImpl">
<property name="itemManagerDAO"><ref bean="itemManagerDAO"/></property>
</bean>
</property>
</bean>
Mas adelante podríamos seguir definiendo nuestro servicios, por ejemplo uno sin propiedades, y con los parámetros de propagación sobreescritos:
<bean id="miServicio" parent="daoTxProxyTemplate">En cuanto a los tipos de propagación para las transacciones y su nivel de aislamiento, lo mas utilizado es simplemente PROPAGATION_REQUIRED, pero podemos optar por todos los definidos en la interfaz TransactionDefinition, utilizando el formato "PROPAGATION_NAME, ISOLATION_NAME, readOnly, timeout_NNNN, +Exception1, -Exception2", siendo PROPAGATION_NAME el único requerido.
<property name="target">
<bean class="com.example.services.otroServicio"/>
</property>
<property name="transactionAttributes">
<props>
<prop key="load*">PROPAGATION_REQUIRED,readOnly</prop>
</props>
</property>
</bean>
En la definición de la plantilla de transacciones, también definimos una propiedad transactionManager. Este bean, puede tomar la forma de
<bean id="transactionManager"si trabajamos con JDBC directamente, o
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource"><ref bean="defaultDataSource"/></property>
</bean>
<bean id="transactionManager"si utilizamos Hibernate.
class="org.springframework.orm.hibernate.HibernateTransactionManager">
<property name="sessionFactory"><ref local="sessionFactory"/></property>
</bean>
Queda para otro post como definir el sessionFactory de Hibernate y el dataSource (con pooling o sin el) necesarios.
1 comentario:
Hola lo que no veo es con esto de las transacciones delarativas no hace falta hacer el rollback en el código java?.
Es decir solo se configura con esta declaración
Publicar un comentario