@Transactional

¿Porque escribir un post sobre esta anotación?, porque me ha tenido 16h bloqueado. En un principio parece que hay que usarla a nivel de clase.Posteriormente, leyendo en stackoverflow, te dicen que a nivel de método. Oki. Tampoco va. Porque tiene que ser a nivel de clase y de método. Olé.¿Porqué?
Ejemplo en el manual de Spring. ¿Alguien ve anotaciones a nivel de método?

// the service class that we want to make transactional

@Transactional
public class DefaultFooService implements FooService {

 Foo getFoo(String fooName);
 Foo getFoo(String fooName, String barName);
 void insertFoo(Foo foo);
 void updateFoo(Foo foo);

}

Su applicationContext.xml


<!-- from the file 'context.xml' -->
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">

<!-- this is the service object that we want to make transactional -->
<bean id="fooService" class="x.y.service.DefaultFooService"/>

<!-- enable the configuration of transactional behavior based on annotations -->
<tx:annotation-driven transaction-manager="txManager"/>

<!-- a PlatformTransactionManager is still required -->
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!-- (this dependency is defined somewhere else) -->
<property name="dataSource" ref="dataSource"/>
</bean>

<!-- other <bean/> definitions here -->

</beans>

Del manual de Spring:

Si  <bean id=”txManager”> se llamase transactionManager, entonces no haría falta ponerlo en: <tx:annotation-driven transaction-manager=”txManager”/>. Se quedaria: <tx:annotation-driven />.

“You can place the @Transactional annotation before an interface definition, a method on an interface, a class definition, or a public method on a class. However, the mere presence of the @Transactional annotation is not enough to activate the transactional behavior.” Es decir se puede poner conjuntamente, pero no aclara que debe ser asi.

“Spring recommends that you only annotate concrete classes (and methods of concrete classes) with the @Transactional annotation, as opposed to annotating interfaces.” Si no es una interfaz… si es una clase… la anotación va en la clase y en el método… puff.

¿Porque no usarlo en interfaces?. Porque si utilizas <tx:annotation-driven mode=”aspectj”/> ó <tx:annotation-driven proxy-target-class=”true”/>. Spring no va a poder hacer su magia.

Cuidadin con poner @Transactional y @Service juntas…

“The most derived location takes precedence when evaluating the transactional settings for a method”. Es decir si tienes la anotacion a nivel de clase y de metodo, prevalece la del metodo. La configuracion que introduzcas en el metodo tienen prioridad sobre la configuracion de la anotacion en la clase. Ej: si en la clase, la transaccion es de solo lectura, y en el metodo de escritura, ese metodo podra escribir.

@Transactional(readOnly = true)
public class DefaultFooService implements FooService {

  public Foo getFoo(String fooName) {
    // do something
  }

  // these settings have precedence for this method
  @Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW)
  public void updateFoo(Foo foo) {
    // do something
  }
}

Cuando usas proxy, la anotación solo es viable en métodos públicos. No se lanzara ningún error, pero el proxy no los podrá ver. Si por alguna razón, necesitas métodos de otro tipo, protected ó private, utiliza mejor aspectos.

Bien, esto ya ha terminado, ¿donde pone que es obligatorio que el método y la clase deban tener la anotacion @Transaction?. Si no lo haces así, no funciona.

Anuncios
@Transactional