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
Vous devez vous connecter pour publier un commentaire.
Vous avez à injecter le gestionnaire de transactions dans la classe que vous souhaitez utiliser. Vous pouvez utiliser le constructeur ou des biens d'injection ou d'utilisation permettra à l'autowiring.
On vous l'opération de la crèche, vous pouvez utiliser la programmation du soutien à la transaction, au Printemps, de début et de valider la transaction. Voici un exemple de code à partir du Printemps de référence 2.5:
Voir le référence pour plus de détails.