<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
lazy-init="true">
<property name="dataSource" ref="dataSource" />
</bean>
使用spring和hibernate构建应用程序时,如果我使用DataSourceTransactionManager
,那么在异常时,它不会回滚。好像它在不同的会话中使用auto-comit。但是,如果我将事务管理器更改为org.springframework.orm.hibernate3.HibernateTransactionManager
,则回滚将按预期工作。
或者,如果我们使用hibernate,那么我们需要使用HibernateTransactionManager
吗?
N.b:我的服务使用@Transactional(rollbackFor = { Throwable.class} )
答案 0 :(得分:3)
使用普通休眠时,需要以下内容来管理事务
Session s = sessionfactory.openSession();
Transaction tx = null;
try {
tx = s.beginTransaction();
// Your data manipulation here
tx.commit();
} catch (Exception e) {
if (tx != null) { tx.rollback();}
} finally {
s.close();
}
这也是HibernateTransactionManager
的作用(如果需要,打开会话,启动事务,然后提交/回滚)。
现在你要做的是以下(这是DataSourceTransactionManager
的类似物,它对`DataSource而不是会话进行操作。)
Session s = sessionfactory.openSession();
Connection conn = null;
try {
conn = s.connection();
// Your data manipulation here
conn.commit();
} catch (Exception e) {
if (conn != null) {
try {
conn.rollback();
catch (IOExceptin) {}
}
} finally {
s.close();
}
这不会起作用,因为实际的事务单元会话永远不会被告知提交或回滚。因此,在最坏的情况下,根据您的刷新模式,所有(或部分)都会被提交。
简而言之,始终使用适合您技术的交易管理器。
使用普通休眠时使用HibernateTransactionManager
,在使用JPA时使用JpaTransactionManager
,请不要在这些情况下使用DataSourceTransactionManager
,因为只有在的情况下才可以使用Session
只使用普通JDBC。
DataSourceTransactionManager
明确指出它在DataSource和底层连接上运行。当一个人使用Hibernate时,事务由休眠EntityManager
控制,这是HibernateTransactionManager
操作的级别。对于JPA,这是{{1}},这是JpaTransactionManager
认可的内容。
答案 1 :(得分:0)
PlatformTransactionManager实现通常需要知识 他们工作的环境:JDBC,JTA,Hibernate等 上。
如果在Java EE容器中使用JTA,则使用容器 DataSource,通过JNDI获得,与Spring一起获得 的JtaTransactionManager。
您也可以轻松使用Hibernate本地交易......
在这种情况下,您需要定义一个Hibernate LocalSessionFactoryBean, 您的应用程序代码将用于获取Hibernate Session 实例...在这种情况下是HibernateTransactionManager类型。
与DataSourceTransactionManager需要引用的方式相同 对于DataSource,HibernateTransactionManager需要一个引用 到SessionFactory。
虽然:
DataSourceTransactionManager将绑定JDBC连接 指定DataSource到当前线程,可能允许 一个线程绑定的每个DataSource连接。
会话不会受到当前交易的约束,您需要两者进行本地交易。
这就是hibernate或JPA特定的TM会为您做的事情。它们将关联持久化上下文和每个线程的每个事务一个连接。
如果您选择JTA交易,则外部TM将协调交易。数据库连接将在每个语句之后积极释放,只要外部TM在全局事务生命周期内始终将相同的连接返回到同一个线程,这就很好。