[英]Spring 3 problems with TransactionManager and annotations
我正在尝试在我的 Web 应用程序(由 Spring MVC 3 提供支持)中设置一个TransactionManager
,因为我需要一个组件的方法注释为@Transactional
。
这是我的情况:
web.xml
: load 2 xml files for the Spring ContextLoaderListener
( applicationContext.xml
and database.xml
)@Transactional
方法)database.xml
:包含数据源(我使用来自 commons-dbcp 的BasicDataSource
)、事务管理器定义和 tx:annotation-driven。 我有一个@Component
(DeleteComponent
),它有一个接口和一个实现 ( DeleteComponentImpl
)。 实现 class 用@Component
注释,并且有一个用@Transactional
注释的公共方法(我注释了具体的 class 而不是接口,如 Spring 文档所述)。 对于@Transactional
,我没有放任何 arguments,因为默认值很好。 这个 class 有一些通过@Autowired
注入的 DAO(用@Repository
注释)。 我只使用普通的 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"/>
该应用程序仍然正确部署并且没有抱怨。
关于我应该检查什么以使其正常工作的任何提示?
谢谢。
我通过使用@Transactional(rollbackFor = RuntimeException.class)
并从BasicDataSource
切换到 c3p0 库中存在的ComboPooled
来解决。 不过感谢您的建议。
要在抛出异常时回滚,请添加:
@Transactional(rollbackFor=Exception.class)
您还需要设置 transactionManger bean(这是我的,使用 hibernate):
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"
p:sessionFactory-ref="sessionFactory" />
我发现本教程内容丰富。
我相信@Autowired
和@Resource
不会被@Component
上的 Spring 扫描。 尝试使用ContextHolder
class 来获取上下文和 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;
}
}
并通过以下方式调用您的 dao:
ContextHolder.getApplicationContext().getBean("MyDAO");
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.