java - JCA ManagedConnection 生命周期

标签 java weblogic jca

目前,我开发了一个 JCA 出站适配器(支持 LocalTransaction),但在连接管理方面遇到了一些问题。我的适配器运行良好,但服务器 (WebLogic 12c) 没有将 ManagedConnections 放回到池中。根据 JavaDoc,服务器必须调用 ManagedConnection.cleanup() 来重新初始化连接并将其放回池中,但事实并非如此。

当我使用 EJB 中的适配器时,服务器创建一个新的 ManagedConnection,开始一个新事务,提交它,但不调用 ManagedConnection.cleanup() 方法,也不将其放回到游泳池。

下面你可以看到我的测试bean:

@Stateless(mappedName = "TestingBean")
@Local(value = TestingBeanLocal.class)
@Remote(value = TestingBeanRemote.class)
@TransactionManagement(value = TransactionManagementType.CONTAINER)
@TransactionAttribute(value = TransactionAttributeType.REQUIRES_NEW)
public class TestingBean implements TestingBeanCommon{

@Resource(mappedName = "eis/myJCA")
private MyDataSource dataSource;

@Override
public void performTestAction(String param1, String param2) {
    MyConnection connection = dataSource.getMyConnection();
    connection.performAction(ActionFactory.getSomeAction(param1, param2));
}
}

调用 10 次后,我得到以下结果:

Got Initial context javax.ejb.EJBException: EJB Exception: ; nested exception is: java.lang.RuntimeException: javax.resource.spi.ApplicationServerInternalException: Unable to get a connection for pool = "eis/myJCA", weblogic.common.resourcepool.ResourceLimitException: Configured maximum limit of (0) on number of threads allowed to wait for a resource reached for pool eis/myJCA

正如您所注意到的,它为每次调用使用一个新事务(REQUIRES_NEW 属性)。服务器首先创建一个新的 ManagedConnection 实例 10 次,然后连接池达到其最大容量。

从跟踪日志可以清楚地看出,没有发生任何一次 ManagedConnection.cleanup() 调用,并且池中的每个连接都很忙。我已阅读 JCA 规范,发现适配器可以使用回调函数向监听器发送生命周期事件,但任何使用这些事件监听器回调的尝试都会以新的异常结束:

javax.ejb.EJBException: BEA1-001471C1E76DE5A4E067; nested exception is: weblogic.transaction.nonxa.NonXAException: java.lang.IllegalStateException: [Connector:199175]This ManagedConnection is managed by a container for its transactional behavior and has been enlisted to a JTA transaction by a container; application/adapter must not call the local transaction begin/commit/rollback API. Reject event LOCAL_TRANSACTION_COMMITTED from adapter. javax.ejb.EJBException: EJB Exception: ; nested exception is: java.lang.IllegalStateException: [Connector:199175] This ManagedConnection is managed by a container for its transactional behavior and has been enlisted to a JTA transaction by a container; application/adapter must not call the local transaction begin/commit/rollback API. Reject event LOCAL_TRANSACTION_ROLLEDBACK from adapter.

我想 WebLogic 不会等待任何事件(也许我发送了错误的事件?)。

那么,我做错了什么?如何让服务器将连接放回池中?

UPD:我发现连接事件对服务器非常重要。服务器根据发送到监听器的事件信息来管理连接,并将其注册到 ManagedConnection。现在我支持适配器中的事件,但 WebLogic 仍然不想将连接放回到池中。目前我在日志中收到以下事件:

  1. LOCAL_TRANSACTION_STARTED
  2. CONNECTION_CLOSED
  3. LOCAL_TRANSACTION_COMMITTED

它对我来说看起来不错(CONNECTION_CLOSED 事件意味着应用程序关闭了连接,我添加了发送此事件的 close 方法)。提交成功并且没有出现异常。看起来我已经按正确的顺序发送了事件(之前 WebLogic 抛出异常,但现在停止这样做),但服务器仍然没有将连接放回到池中。

我很困惑。

最佳答案

看来我已经解决了这个问题。当我查看 WebLogic 控制台时,我发现 ManagedConnection 实例有 -1 个 Activity 处理程序。因此,我决定对 MyConnection.close() 方法调用进行注释,我将其添加到测试 bean 中以发送 CONNECTION_CLOSED 事件。完成此更改后,连接池开始正常工作。我尝试修改我的测试 bean 并将其事务属性设置为 NOT_SUPPORTED。之后池中的 ManagedConnections 就有 1 个 Activity 处理程序。所以我放回 MyConnection.close() 行,连接池再次开始工作。

我认为,在事务传播的情况下发送 CONNECTION_CLOSED 事件是错误的。另外,我假设在单个事务的情况下应该使用发送 CONNECTION_CLOSED 事件的方法 ManagedConnection.close() 。但对我来说这似乎很奇怪,WebLogic 不想清理 ManagedConnections 并将它们放回拉取状态(如果它们的 Activity 处理程序数量为负数)。

非常感谢您的帮助。

关于java - JCA ManagedConnection 生命周期,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9783140/

相关文章:

java - 检查一个数组中的所有值是否都存在于另一个数组中

java - Spring MVC。为什么 JSP 页面看不到资源?

java - Glassfish 3.1 ActiveMQ 和 genericra 消费消息

java - 使用 JCA 与 JBoss AS-7 集成 Tuxedo

java - 使用 Play Framework 编译时如何修复包错误。出现错误 : package redis.clients.jedis 不存在

java - MyBatis 是如何处理空结果集的?

jar - 如何在WebLogic中设置jar的顺序?

java - Jdev 12c 集成 weblogic 服务器未启动-bea_wls_internal

java - 套接字异常 : Weblogic

java - 在 JCA 中为 TLS 定义密码套件