我正在尝试在我的Web应用程序中设置一个TransactionManager(由Spring MVC 3提供支持),因为我需要一个组件注释为@Transactional的方法。
这是我的情况:
我有一个@Component(DeleteComponent),它有一个接口和一个实现(DeleteComponentImpl)。实现类使用@Component注释,并且有一个使用@Transactional注释的公共方法(我注释了具体类而不是接口,如Spring文档所述)。对于@Transactional我没有放任何参数,因为默认值很好。这个类有一些DAO(用@Repository注释)通过@Autowired注入。我只使用普通的JDBC(没有Hibernate或其他ORM)。这个@Component被注入一个@Controller(在spring-servlet.xml中定义)。
如果注释为@Transactional的方法抛出异常(未选中,如RuntimeException),则不会回滚任何内容。数据库保留异常之前所做的更改。我正在使用Jetty Web服务器在本地测试我的应用程序。我注意到的事实上似乎没有设置事务管理器。实际上,我的事务管理器名为“transactionManager”。用于设置注释驱动事务的xml行是
<tx:annotation-driven transaction-manager="transactionManager"/>
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
如果我将其更改为使用不存在的bean名称,如
<tx:annotation-driven transaction-manager="fake"/>
应用程序仍然正确部署并且不会抱怨。
有关我应该检查什么以使其正常工作的任何提示?
感谢。
答案 0 :(得分:2)
我通过使用@Transactional(rollbackFor = RuntimeException.class)并从BasicDataSource切换到c3p0库中存在的ComboPooled来解决。谢谢你的建议。
答案 1 :(得分:1)
要在抛出异常时进行回滚,请添加:
@Transactional(rollbackFor=Exception.class)
您还需要设置transactionManger bean(这是我的,使用hibernate):
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"
p:sessionFactory-ref="sessionFactory" />
我发现此tutorial信息丰富。
答案 2 :(得分:-2)
我相信Spring不会在@Component上扫描@Autowired和@Resource。 尝试使用ContextHolder类来获取上下文和DAO
@Component
public class ContextHolder implements ApplicationContextAware {
/**
* Spring context which will directly be injected by Spring itself
*/
private static ApplicationContext context = null;
/**
* Overridden method of ApplicationContextAware, which will automatically be called by the container
*/
public void setApplicationContext(ApplicationContext context) throws BeansException {
this.context = context;
}
/**
/**
* Static method used to get the context
*/
public static ApplicationContext getApplicationContext() {
return context;
}
}
并用:
打电话给你的daoContextHolder.getApplicationContext().getBean("MyDAO");