Comment faire pour la restauration de Printemps de la Transaction lorsqu'une Exception est levée
Je suis à l'aide de printemps 3.0.5 et hibernate 3.6. Dans mon projet, il y a un scénario où je rollback transaction de toute exception dans jetés ou une erreur survient. Cela l'exemple de code, Tout fonctionne bien sauf la transaction n'est pas annulée lorsque je lance une Exception, mais, si une exception est levée comme mysql.IntegrityConstraintException ensuite transaction obtient restaurée, pourquoi ce n'est pas le cas dans mon cas?
applicationContext.xml
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="classpath:database.properties"/>
</bean>
<bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${jdbc.driverClassName}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="myDataSource" />
<property name="packagesToScan" value="com.alw.imps"/>
<property name="configLocation">
<value>
classpath:hibernate.cfg.xml
</value>
</property>
</bean>
<bean id="stateDao" class="com.alw.imps.dao.StateDaoImpl">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
<bean id="stateService" class="com.alw.imps.services.StateService">
<property name="stateDao" ref="stateDao"></property>
<property name="cityDao" ref="cityDao"></property>
<property name="customerDao" ref="customerDao"></property>
</bean>
<bean id="customerDao" class="com.alw.imps.dao.CustomerDaoImpl">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
<bean id="cityDao" class="com.alw.imps.dao.CityDaoImpl">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<tx:advice id = "txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="*" propagation="REQUIRED" />
</tx:attributes>
</tx:advice>
Classe de Service StateService
@Transactional(rollbackFor={Exception.class})
public class StateService {
private StateDaoImpl stateDao;
private CityDao cityDao;
private CustomerDao customerDao;
public void setCustomerDao(CustomerDao customerDao) {
this.customerDao = customerDao;
}
public void setStateDao(StateDaoImpl stateDao) {
this.stateDao = stateDao;
}
public CityDao getCityDao() {
return cityDao;
}
public void setCityDao(CityDao cityDao) {
this.cityDao = cityDao;
}
public void addState() {
try {
State state=new State();
state.setStateName("Delhi");
stateDao.create(state);
addCity();
addCustomer();
} catch(Exception e) {
e.printStackTrace();
}
}
public void addCity() throws Exception {
City city=new City();
city.setCiytName("Delhi");
city.setStateId(1);
cityDao.create(city);
}
public void addCustomer() throws Exception {
throw new java.lang.Exception();
}
DAO
public class StateDaoImpl extends GenericDaoImpl<State, Integer> implements StateDao {
}
GenericDaoImpl
public class GenericDaoImpl<T,PK extends Serializable> implements GenericDao<T,PK> {
public SessionFactory sessionFactory;
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
public Session getSession() {
return sessionFactory.getCurrentSession();
}
public PK create(T o) {
Session ss= getSession();
ss.save(o);
return null;
}
mise en veille prolongée.cfg
<hibernate-configuration>
<session-factory>
<property name="connection.pool_size">1</property>
<property name="dialect">org.hibernate.dialect.MySQLInnoDBDialect</property>
<property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
<property name="show_sql">true</property>
<property name="hbm2ddl.auto">update</property>
<property name="defaultAutoCommit">false</property>
<mapping class="com.alw.imps.pojo.State"/>
<mapping class="com.alw.imps.pojo.City"/>
</session-factory>
</hibernate-configuration>
Donc, comme je l'ai dit, mon problème est que la transaction n'est pas prise en restauration lorsque je lance une exception de type Exception à partir de la méthode ajouteclient()
Je ne crois pas que votre
MyService
classe est prise en proxy. La restauration que vous voyez est à venir à partir de la db, pas de la transaction.Merci de poster votre configuration et de votre pile d'appels avec les signatures de méthode/annotations, afin de pouvoir mieux évaluer la situation.
j'ai ajouté de la configuration et d'autres dépendances,veuillez vérifier la mise à jour
Quelle méthode vous appelez de l'extérieur du service? ajouteclient() ne fait rien d'autres que de lancer une exception. Appelez-vous addState(), dans la réalité?
OriginalL'auteur arvin_codeHunk | 2013-05-07
Vous devez vous connecter pour publier un commentaire.
Votre transaction n'est pas rollbacked parce qu'il n'y est aucune exception n'est levée: le
addState()
méthode que vous appelez les captures de l'exception:De sorte que le transactionnel Printemps proxy ne vois pas l'exception et ne pas annuler la transaction.
Il travaille pour les exceptions levées à partir de la DAO parce que le DAO est lui-même transactionnelle, donc sa propre transactionnelle proxy détecte l'exception levée par les DAO et les marques de l'opération pour la restauration. L'exception est ensuite transmise au service et pris par votre code, mais la transaction est déjà marqué pour la restauration à ce point.
OriginalL'auteur JB Nizet
Votre transaction n'est pas annulée parce que vous ne laissons pas Exception à atteindre au framework Spring, vous êtes à la capture de l'exception dans le code lui-même.
Ainsi, au lieu de
utilisation
OriginalL'auteur Sachin Gorade
La transaction n'a pas été annulée, parce que vous êtes la capture de l'exception de vous-même, par écrit bloc catch..
Cela peut être fait dans les cas normaux, mais au printemps de transaction, si vous le faites, comment le ressort du gestionnaire de transactions sait à l'exception se passe.. c'est pourquoi elle n'est pas annulée.
OriginalL'auteur user2929
Vous pouvez trouver des réponses à la plupart des questions au Printemps doc API.
@Transactional
a un champClass<? extends Throwable>[] rollbackFor()
:Ce sens que, pour les cas suivants, peu importe la façon dont l'appelant traiter les exceptions, seul le premier
RunTimeException
cas d'appel roleback par défaut.Et surtout, vous pouvez vouloir revenir pour checked exceptions undistinguishedly, à l'aide de
@Transactional(rollbackFor = Exception.class)
OriginalL'auteur Tiina