我有一个使用Bean管理事务的EJB:
@Singleton
@TransactionManagement(TransactionManagementType.BEAN)
public class BmtBean {
@Resource
private DataSource ds1;
@Resource
private SessionContext sessionCtx;
@EJB
private CmtBean cmtBean;
public void callCmtBean() {
Connection conn1 = null;
try {
conn1 = ds1.getConnection();
// create a PreparedStatement and execute a query
// process result set
while(resultSet.next()) {
// map resultSet to an entity
Entity entity = mapResultSetToEntity(resultSet);
sessionCtx.getUserTransaction().begin();
// pass an entity to another EJB,
// that operates on a different JTA data source
cmtBean.call(entity);
sessionCtx.getUserTransaction().commit();
}
} finally {
// release connection
}
}
}
另一个带有容器管理事务的bean:
@Singleton
@TransactionManagement(TransactionManagementType.CONTAINER)
public class CmtBean {
@PersistenceContext
private EntityManager em;
@TransactionAttribute(TransactionAttributeType.MANDATORY)
public void call(Entity entities) {
//persist passed entities
//em.flush()
//em.clear();
}
}
致电cmtBean#call
并不会导致TransactionRequiredException
,因为在此之前我开始UserTransaction
。但是当调用em#flush
时,抛出此异常:
引起:javax.resource.spi.ResourceAllocationException:错误 分配连接。原因:java.lang.IllegalStateException:Local 事务已经有1个非XA资源:无法添加更多资源。
在挖掘了一些EclipseLink代码后,我发现在调用em#flush()
时,它会尝试从dataSource
获取新连接,但未能这样做。
这是一个错误还是预期的行为?我该如何解决这个问题?
更新
请参阅更新的代码示例。
另外,我必须强调,我确实使用了2个非XA JTA数据源。但由于BmtBean
中的连接默认设置为autocommit
,因此在调用CmtBean
时,必须已提交事务。