java - 全局事务管理-Jboss : Closing a connection for you

标签 java spring hibernate jboss transactions

我们在 jboss 7 服务器上部署了一个 spring 应用程序。

该应用程序使用通过jndi 从jboss 获取的多个数据源。

事务管理也由 Java EE 容器提供(我们使用 Spring JtaTransactionManager)

应用程序架构是一个遗留的 DAO 扩展 hibernate 模板(使用 Spring HibernateDaoSupport)。

事务在服务层使用@Transactional注解进行管理。

我的第一个问题是:

  • 遇到注解,事务管理器如何知道事务中会涉及到哪些数据源?

  • 它何时有效地检索 JDBC 连接以及在哪些数据源上?它什么时候有效地打开交易? (只有 DAO 获得了对绑定(bind)到特定数据源的 sessionFactory 的引用)。

我们使用的驱动程序不支持分布式 (XA) 事务,在大多数情况下我们不需要多阶段提交,因为只编写了一个数据源。无论如何,当我们在同一事务中访问(只读)其他数据源时,我们会在日志中收到消息:

INFO  [org.jboss.jca.core.api.connectionmanager.ccm.CachedConnectionManager] (http--0.0.0.0-8080-4) IJ000100: Closing a connection for you. Please close them yourself: org.jboss.jca.adapters.jdbc.jdk6.WrappedConnectionJDK6@691644c: java.lang.Throwable: STACKTRACE
at org.jboss.jca.core.connectionmanager.ccm.CachedConnectionManagerImpl.registerConnection(CachedConnectionManagerImpl.java:265)
at org.jboss.jca.core.connectionmanager.AbstractConnectionManager.allocateConnection(AbstractConnectionManager.java:495)
at org.jboss.jca.adapters.jdbc.WrapperDataSource.getConnection(WrapperDataSource.java:129)
at org.springframework.orm.hibernate3.LocalDataSourceConnectionProvider.getConnection(LocalDataSourceConnectionProvider.java:81) [spring-orm-3.0.5.RELEASE.jar:3.0.5.RELEASE]
at org.hibernate.jdbc.ConnectionManager.openConnection(ConnectionManager.java:446) [hibernate-core-3.3.1.GA.jar:3.3.1.GA]
[...]
  • 有没有办法在不使用 XA 数据源的情况下正确管理连接释放?

  • 否则可以安全地忽略这些消息,还是它们表示真正的问题? (日志级别为INFO)

[编辑]

关于配置的一些附加数据:

数据源声明示例

<!-- JNDI datasource -->
<bean id="customersDataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
    <property name="jndiName" value="java:comp/env/${shared.datasource}" />
</bean>

关联的sessionFactory

<bean id="sharedSessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
    <property name="dataSource" ref="customersDataSource" />
    <property name="configLocation" value="classpath:hibernate.shared.cfg.xml" />
    <property name="hibernateProperties">
        <props>
            <!-- jboss specific transaction management -->
            <prop key="transaction.factory_class">org.hibernate.transaction.JTATransactionFactory</prop>
            <prop key="transaction.manager_lookup_class">org.hibernate.transaction.JBossTransactionManagerLookup</prop>
            <prop key="hibernate.connection.release_mode">after_transaction</prop>
            <prop key="hibernate.transaction.auto_close_session">true</prop>
            [...]
        </props>
    </property>
</bean>

我们正在考虑使用 hibernate.connection.release_mode,但即使在单个事务中实际上只写入一个数据源,它也不总是相同的。

最佳答案

When encountering the annotation, how does the transaction manager know which datasources will be involved in the transaction ?

只要你有:

<tx:annotation-driven/>

Spring 应该使用 TransactionInterceptor 来拦截您的服务方法调用并将请求包装在 JTA 事务中。

Spring 没有实际的 XA 事务管理器,JtaTransactionManager 只是一个需要后端 JTA 提供程序(如 JBoss AS 事务管理器)的外观。

你还需要配置Jboss TM,像这样:

<bean id="jbossTransactionManager" class="com.arjuna.ats.internal.jta.transaction.arjunacore.TransactionManagerImple">
</bean>

When does it effectively retrieve a JDBC connection and on which datasources ? when does it effectively open a transaction ? (only DAOs got a reference to the sessionFactory bound to a specific datasource).

事务由 JtaTransactionManager 触发,它将实际的事务初始化请求委托(delegate)给 JBoss TM。

所有数据源都必须符合 XA,不能将 JTA 与资源本地数据源混合使用。某些事务管理器可能会使用 LastResourceCommit 优化,允许您征用最多一个非 XA 数据源。

当需要数据库连接时,数据源在当前事务中登记:

DataSource.getConnection()

从此时开始,此连接将参与当前事务,因此将根据事务结果提交或回滚。

我认为您不应该使用 LocalDataSourceConnectionProvider。您需要设置:

<jta-data-source>java:/WareHouseDS</jta-data-source>

<property name="hibernate.transaction.manager_lookup_class" value="org.hibernate.transaction.JBossTransactionManagerLookup" />

Hibernate 需要知道从哪里获取已注册数据源的 JBoss AS JNDI。

关于java - 全局事务管理-Jboss : Closing a connection for you,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23913665/

相关文章:

java - 缓存查询结果

java - Spring Security 无法在/spring_security_login 生成/映射默认登录页面

java - 应该填充的集合为空

java - 将 Hibernate xml 配置文件从 hypersql 转换为 mssql

java - Perl 或 Java 情感分析

java - 如何修改 javax.json.JsonObject 对象?

java - spring框架mvc能替代struts吗?或者我很困惑?

java - Apache Camel 动态消费者

java - 可嵌入对象集合的级联删除

java - 如何在类之间共享数据库连接? (JDBC)