【发布时间】:2011-02-22 03:27:33
【问题描述】:
在阅读了有关此错误的先前问题后,似乎所有人都得出结论,您需要在所有数据源上启用 XA。但是:
- 如果我不想要分布式怎么办? 交易?如果我想我会怎么做 在两个不同的地方开始交易 同时数据库,但 在一个数据库上提交事务 并回滚事务 另一个?
- 我想知道我的代码如何 实际上发起了一个分布式 交易。在我看来,我是 开始完全分开 每一笔交易 数据库。
申请信息:
应用程序是在 Sun Java Application Server 9.1 上运行的 EJB
我使用类似下面的 spring 上下文来设置休眠会话工厂:
<bean id="dbADatasource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="jdbc/dbA"/>
</bean>
<bean id="dbASessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dbADatasource" />
<property name="hibernateProperties">
hibernate.dialect=org.hibernate.dialect.Oracle9Dialect
hibernate.default_schema=schemaA
</property>
<property name="mappingResources">
[mapping resources...]
</property>
</bean>
<bean id="dbBDatasource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="jdbc/dbB"/>
</bean>
<bean id="dbBSessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dbBDatasource" />
<property name="hibernateProperties">
hibernate.dialect=org.hibernate.dialect.Oracle9Dialect
hibernate.default_schema=schemaB
</property>
<property name="mappingResources">
[mapping resources...]
</property>
</bean>
这两个 JNDI 资源都是 javax.sql.ConnectionPoolDatasoure 的。它们实际上都指向同一个连接池,但我们有两个不同的 JNDI 资源,因为这两个完全独立的表组将来可能会移动到不同的数据库。
然后在代码中,我这样做:
sessionA = dbASessionFactory.openSession();
sessionB = dbBSessionFactory.openSession();
sessionA.beginTransaction();
sessionB.beginTransaction();
sessionB.beginTransaction() 行会在这篇文章的标题中产生错误 - 有时。我在两个不同的 sun 应用程序服务器上运行该应用程序。一个运行良好,另一个抛出错误。我看不出两台服务器的配置方式有什么不同,尽管它们确实连接到不同但等效的数据库。
所以问题是
- 为什么上面的代码没有启动 完全独立的交易?
- 如何强制启动 独立交易而不是 分布式事务?
- 什么配置可能导致差异 两个应用程序之间的行为 服务器?
谢谢。
附:堆栈跟踪是:
Local transaction already has 1 non-XA Resource: cannot add more resources.
at com.sun.enterprise.distributedtx.J2EETransactionManagerOpt.enlistResource(J2EETransactionManagerOpt.java:124)
at com.sun.enterprise.resource.ResourceManagerImpl.registerResource(ResourceManagerImpl.java:144)
at com.sun.enterprise.resource.ResourceManagerImpl.enlistResource(ResourceManagerImpl.java:102)
at com.sun.enterprise.resource.PoolManagerImpl.getResource(PoolManagerImpl.java:216)
at com.sun.enterprise.connectors.ConnectionManagerImpl.internalGetConnection(ConnectionManagerImpl.java:327)
at com.sun.enterprise.connectors.ConnectionManagerImpl.allocateConnection(ConnectionManagerImpl.java:189)
at com.sun.enterprise.connectors.ConnectionManagerImpl.allocateConnection(ConnectionManagerImpl.java:165)
at com.sun.enterprise.connectors.ConnectionManagerImpl.allocateConnection(ConnectionManagerImpl.java:158)
at com.sun.gjc.spi.base.DataSource.getConnection(DataSource.java:108)
at org.springframework.orm.hibernate3.LocalDataSourceConnectionProvider.getConnection(LocalDataSourceConnectionProvider.java:82)
at org.hibernate.jdbc.ConnectionManager.openConnection(ConnectionManager.java:446)
at org.hibernate.jdbc.ConnectionManager.getConnection(ConnectionManager.java:167)
at org.hibernate.jdbc.JDBCContext.connection(JDBCContext.java:142)
at org.hibernate.transaction.JDBCTransaction.begin(JDBCTransaction.java:85)
at org.hibernate.impl.SessionImpl.beginTransaction(SessionImpl.java:1354)
at [application code ...]
【问题讨论】:
-
连接池设置中的“非事务性连接”复选框起到了作用。奇怪的是,它在两个应用服务器中都未选中,但显然其中一个正在返回非事务连接。