Comment programmer le gestionnaire de transactions dans un thread?

J'ai un guichet page , qui contient deux Printemps-managed beans , on est DAO , un autre est un Objet de Service :

public class MergeAccountsPage extends WebPage
{
  @SpringBean
  private MergeEmailDao mergeEmailDao;

  @SpringBean
  private MergingService mergingService;
}

La MergingService's la mise en œuvre de méthodes sont pour la plupart annoté avec @Transactional , de sorte que chaque action impliquant MergingService fonctionne très bien.

Mais le problème vient ici :

Link<Void> link = new Link<Void>("cancelLink") {
  @Override
  public void onClick()  {
    ma.setNewEmail(null);
    ma.setNewEmailClicked(null);
    ma.setNewEmailSentTime(null);
    mergeAccoungDao.update(ma); //not written to DB
    setResponsePage(...);
  }
};

Le lien d'appel mergeAccoungDao.update(ma) mettre à jour une ligne dans la DB.

Mais les données ne sont pas mis à jour la DB , je pense que c'est parce que le DAO n'est pas enveloppé dans @Transaction, ni tx:advice et aop balises.

Je me demande est-il possible d'obtenir par programme le gestionnaire de transactions , et manuellement ouvrir/fermer la transaction ?

Note: je peux résoudre le problème en ajoutant ce code dans le printemps XML :

  <tx:advice id="txAdviceApp" transaction-manager="transactionManagerApp">
    <tx:attributes>
      <tx:method name="get*"    read-only="true"/>
      <tx:method name="save*"   propagation="REQUIRED"/>
      <tx:method name="update*" propagation="REQUIRED"/>
      <tx:method name="delete*" propagation="REQUIRED"/>
      <tx:method name="*" propagation="SUPPORTS"/>
    </tx:attributes>
  </tx:advice>

  <aop:config>
    <aop:pointcut id="methods" expression="execution(* destiny.utils.AbstractDao+.*(..))"/>
    <aop:advisor advice-ref="txAdviceApp" pointcut-ref="methods"/>
  </aop:config>

De sorte que le DAO enregistrer/mettre à jour/supprimer fonctionnera comme un charme.

Mais je n'avais pas à ajouter cette config . Parce qu'en fait , le DAO étend une AbstractDao , et il y a d'autres DB/DAOs étendre cette AbstractDao :

public interface AbstractDao<T> {
  public T get(Serializable id);
  public T save(T t);
  public T update(T t);
  public void delete(T t);
}

public abstract class AbstractDaoJpaImpl<T> implements AbstractDao<T>

public interface MergeAccountDao extends AbstractDao<MergeAccount>

@Repository
public class MergeAccountDaoImpl extends AbstractDaoJpaImpl<MergeAccount> implements MergeAccountDao

Par conséquent , si ce AbstractDAO du CRUD est "conseillé" par cette transactionManagerApp , d'autres DAOs peuvent avoir un problème , parce que d'autres DAOs peut dépendre txManagerForum , txManagerBank , txManagerUser ...etc.

De retour au problème , il est un moyen d'obtenir par programme txManager ? Tels que :

TransactionManager txManager = TxManagerThreadLocal.get();
txManager.begin();
ma.setNewEmailSentTime(null);
mergeAccoungDao.update(ma); 
txManager.commit();

Ou est-il une meilleure façon de s'envelopper d'une transaction à la DAO ?

Merci beaucoup.

source d'informationauteur smallufo