在我的Spring 2.5.6 + Hibernate应用程序中,我需要使用不同的模式向/从多个数据库读取/写入数据。该应用程序位于Tomcat上,因此暂时我不想使用JTA,因此我不需要迁移到成熟的应用程序服务器。
所以我决定只有一个事务数据源。我可以和其他不是交易的人一起生活。
但不知怎的,我无法让它发挥作用。你能不能给我一个关于我可能做错什么的线索?
这是我的applicationContext.xml:
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<!-- ..configuration.. -->
</bean>
<bean id="nonTransactionalSessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="nonTransactionalDataSource" />
<!-- ..configuration.. -->
</bean>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<!-- ..configuration.. -->
</bean>
<bean id="nonTransactionalDataSource" class="org.apache.commons.dbcp.BasicDataSource">
<!-- ..configuration.. -->
</bean>
<bean id="txManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<bean id="daoHolder" class="com.app.services.TransactionTest$DaoHolder"/>
<tx:annotation-driven transaction-manager="txManager"/>
<bean id="transactionalDao" class="com.app.services.TransactionalDaoImpl">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<bean id="nonTransactionalDao" class="com.app.services.NonTransactionalDaoImpl">
<property name="sessionFactory" ref="nonTransactionalSessionFactory" />
</bean>
正如您所看到的,上面只是两个会话工厂的定义,每个工厂都使用自己的数据源。事务管理器仅使用其中一个会话工厂,并配置了注释驱动的tx-management。
这是我的单元测试,我正在尝试测试事务行为:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"/applicationContext.xml"})
public class TransactionTest {
@Autowired
private DaoHolder daoHolder;
@Test
public void testTransactions() throws Exception {
try {
daoHolder.runTransactionalMethod();
} catch (Exception exception) {
System.out.println("Exception caught");
}
}
public static class DaoHolder {
@Autowired
private TransactionalDao transactionalDao;
@Autowired
private NonTransactionalDao nonTransactionalDao;
@Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW, rollbackFor={Exception.class})
private void runTransactionalMethod() throws Exception {
transactionalDao.insertRow();
nonTransactionalDao.insertRow();
throw new Exception();
}
}
作为上述测试的结果,我希望在非事务数据源中插入一个新行,因为事务数据源的更改应该回滚,因为抛出了一个异常。但是,经过这个测试后,我看到两个数据源都插入了行。
编辑:我搬家了一下。我把DaoHolder变成了一个接口,将上面的逻辑移到了一个实现接口的类(DaoHolderImpl)中,并用@Transactional标记了类(不仅仅是方法)。我还将此类添加为Spring Bean。所以现在Spring处理我的交易。但是这一次,当抛出异常时,新行将从两个数据源回滚,而不仅仅是事务性数据源。这仍然不是我所期待的:/
有谁看到我做错了什么? 提前谢谢,
彼得
答案 0 :(得分:1)
如何将断点放在“抛出异常”行,以便您可以查看一个或两个数据库是否具有该行?
它不会修复您的奇怪回滚而不会出现问题,但可能会告诉您非事务性数据源是否运行良好。
您宁愿启用spring / hibernate日志记录来查看有关事务的信息......