1. Les transactions du printemps ne seront pas annulées. J'ai essayé toutes les méthodes en ligne mais en vain.
2. La configuration est la suivante :
<context:component-scan base-package="com.szcshl">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
<context:component-scan base-package="com.szcshl" use-default-filters="false">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
<!-- 配置事务管理器 -->
<bean name="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
<!-- 注解方式配置事物 -->
<!-- <tx:annotation-driven transaction-manager="transactionManager" /> -->
<!-- 拦截器方式配置事物 -->
<tx:advice id="transactionAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="add*" />
<tx:method name="save*" />
<tx:method name="update*" />
<tx:method name="modify*" />
<tx:method name="edit*" />
<tx:method name="delete*" />
<tx:method name="remove*" />
<tx:method name="repair" />
<tx:method name="deleteAndRepair" />
<tx:method name="get*" propagation="SUPPORTS" read-only="true" />
<tx:method name="find*" propagation="SUPPORTS" read-only="true" />
<tx:method name="load*" propagation="SUPPORTS" read-only="true" />
<tx:method name="search*" propagation="SUPPORTS" read-only="true" />
<tx:method name="datagrid*" propagation="SUPPORTS" read-only="true" />
<tx:method name="*" propagation="SUPPORTS" read-only="true" />
</tx:attributes>
</tx:advice>
<aop:config>
<aop:pointcut id="transactionPointcut" expression="execution(* com.szcshl.service..*Impl.*(..))" />
<aop:advisor pointcut-ref="transactionPointcut" advice-ref="transactionAdvice" />
</aop:config>
@RequestMapping(value = "/Save" , method= RequestMethod.POST)
public void departmentSave(Department department, HttpServletResponse response){
departmentService.save(department);
throw new RuntimeException("抛出异常");
}
@Service
@Transactional
public class DepartmentServiceImpl extends BaseServiceImpl<Department> implements DepartmentService {
@Autowired
private DepartmentDao deptDao;
......
public void save(Department entity) {
deptDao.save(entity);
}
}
public class BaseDaoImpl<T> implements BaseDao<T> {
private SessionFactory sessionFactory;
protected Class<T> entityClass;
public SessionFactory getSessionFactory() {
return sessionFactory;
}
@Resource
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
public Session getCurrentSession() {
return this.sessionFactory.getCurrentSession();
}
@SuppressWarnings("rawtypes")
protected Class getEntityClass() {
if (entityClass == null) {
entityClass = (Class<T>) ((ParameterizedType) getClass()
.getGenericSuperclass()).getActualTypeArguments()[0];
}
return entityClass;
}
@Transactional
public Serializable save(T entity) {
return this.getCurrentSession().save(entity);
}
......
}
En y regardant, vous gérez les transactions sur l'interface du service, pas sur le contrôleur
L'exception que vous lancez est dans le contrôleur, bien sûr la transaction ne sera pas annulée
Vous essayez de l'enregistrer dans la classe d'implémentation du service, puis lancez une exception pour voir si la sauvegarde réussit ou non
PS : MySQL dispose de deux moteurs de stockage (couramment utilisés), l'un est InnoDB et l'autre est MyISAM. Le premier prend en charge les verrous, les transactions et les clés étrangères au niveau des lignes, tandis que le second ne prend pas en charge
.Vous avez raison ce que vous avez dit ci-dessus. Les transactions Spring agissent sur la couche de service lorsque la méthode de service lève une exception, la transaction est annulée. Votre bonne pratique de test devrait donc consister à lever des exceptions dans les méthodes de la couche de service.