我有一个访问两个数据库的应用程序。显然,如果我需要跨两个DB的事务,我需要使用两阶段提交之类的东西。但我现在不需要这个保证之王,我不需要一切都是交易的。事情可能会崩溃或独立成功,应用程序可以处理它,而不是最终处于不一致状态。
现在我有一个像这样的设置(删除接口,代码等,以使其尽可能简单地解释):
两个数据来源:
<bean id="firstDS" class="org.springframework.jndi.JndiObjectFactoryBean">
<qualifier value="firstDS" />
<property name="jndiName" value="java:comp/env/jdbc/firstDS" />
</bean>
<bean id="secondDS" class="org.springframework.jndi.JndiObjectFactoryBean">
<qualifier value="secondDS" />
<property name="jndiName" value="java:comp/env/jdbc/secondDS" />
</bean>
只有一个数据源的一个事务管理器:
<tx:annotation-driven transaction-manager="transactionManager" />
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="firstDS" />
</bean>
服务:
@Service
@Transactional(propagation = Propagation.REQUIRED)
public class Service {
@Autowired
private FirstDao firstDao;
@Autowired
private SecondDao secondDao;
public void updateStuff() {
firstDao.updateStuff();
secondDao.updateStuff();
}
}
和两个DAO:
@Transactional(propagation = Propagation.MANDATORY)
public class FirstDao {
@Autowired
@Qualifier("firstDS")
private DataSource dataSource;
public void updateStuff() {
// updates stuff in the first database using dataSource
}
}
@Transactional(propagation = Propagation.MANDATORY)
public class SecondDao {
@Autowired
@Qualifier("secondDS")
private DataSource dataSource;
public void updateStuff() {
// updates stuff in the second database using dataSource
}
}
现在,这没有问题(或至少没有我能观察到的),但我的问题是:
我已经在线阅读了参考文献和各种帖子,但我仍然不确定这种行为。
答案 0 :(得分:1)
安全吗?
没有。 SecondDao.updateStuff
将在没有逻辑事务的情况下执行。这意味着在SecondDao.updateStuff
期间执行的每个查询都将在自动提交模式下以单独的物理事务执行。换句话说:SecondDao.updateStuff
不是事务性的(甚至可能为每个查询使用一个单独的连接......这可能导致性能问题)。
你能做什么?
首先为您的secondDS声明一个transactionManager:
<tx:annotation-driven/>
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="firstDS" />
</bean>
<bean id="transactionManager2" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="secondDS" />
</bean>
然后指定SecondDAO使用transactionManger2:
@Transactional(value="transactionManager2",propagation = Propagation.REQUIRED)
public class SecondDao {
@Autowired
@Qualifier("secondDS")
private DataSource dataSource;
public void updateStuff() {
// updates stuff in the second database using dataSource
}
}