OSGi中的数据库连接未关闭
我有一个OSGi包,它需要将数据持久化到数据库中。如上所述,我发现为了使事务按预期工作,我需要使用XADataSource连接到数据库。但是,当我这样做时,我看到应用程序打开的与数据库的连接从未关闭,这当然会导致数据库在一段时间后无法接受更多的连接 我的设置如下所示: 我有一个创建数据源的包,它只包含一个blueprint.xml文件,其中包含以下内容OSGi中的数据库连接未关闭,osgi,database-connection,openjpa,apache-commons-dbcp,aries,Osgi,Database Connection,Openjpa,Apache Commons Dbcp,Aries,我有一个OSGi包,它需要将数据持久化到数据库中。如上所述,我发现为了使事务按预期工作,我需要使用XADataSource连接到数据库。但是,当我这样做时,我看到应用程序打开的与数据库的连接从未关闭,这当然会导致数据库在一段时间后无法接受更多的连接 我的设置如下所示: 我有一个创建数据源的包,它只包含一个blueprint.xml文件,其中包含以下内容 <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
<bean id="dataSource" class="com.mysql.jdbc.jdbc2.optional.MysqlDataSource">
<property name="url" value="jdbc:mysql://localhost:3306/myschema"/>
<property name="user" value="user"/>
<property name="password" value="pass"/>
</bean>
<service interface="javax.sql.XADataSource" ref="dataSource">
<service-properties>
<entry key="osgi.jndi.service.name" value="jdbc/mysqlds"/>
</service-properties>
</service>
</blueprint>
然后在保存数据的包中,我有一个persistence.xml
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="mypu" transaction-type="JTA">
<jta-data-source>osgi:service/javax.sql.DataSource/(osgi.jndi.service.name=jdbc/mysqlds)
</jta-data-source>
</persistence-unit>
</persistence>
osgi:service/javax.sql.DataSource/(osgi.jndi.service.name=jdbc/mysqlds)
我还指定我的服务方法应该在blueprint.xml中的事务中运行
<bean id="MyServiceImpl"
class="com.test.impl.MyServiceImpl">
<jpa:context property="em" unitname="mypu" />
<tx:transaction method="*" value="Required" />
</bean>
<service id="MyService" ref="MyServiceImpl" interface="com.test.api.MyService" />
我在Karaf中通过bundle进行部署,使用Aries和OpenJPA进行持久化,同时我还部署了Aries事务包装包(org.apache.Aries.transaction.wrappers),以便在事务管理器中登记我的XA资源
你知道我的配置中缺少什么吗
编辑:
经过更多的搜索,我发现这表明我遇到的问题是MySQL的DBCP错误。但是,我不知道如何用OpenJPA可以使用的其他连接池实现来替换DBCP。任何建议都非常受欢迎。我使用commons dbcp创建了一个连接池,该连接池还使用以下配置登记XA连接:
<bean id="myXAEnabledConnectionPoolDataSource" class="org.apache.commons.dbcp.managed.BasicManagedDataSource" destroy-method="close">
<property name="xaDataSourceInstance" ref="mysqlXADataSourceBean" />
<property name="transactionManager" ref="transactionManager" />
</bean>
您可以基于javax.transaction.TransactionManager接口获取事务管理器作为参考
通过这种方式,commons dbcp将正确处理连接的生命周期。请注意,destroy方法存在,因此当blueprint容器停止时,连接池将关闭
编辑:
1-2年前,我也遇到了同样的问题,但是PostgreSQL。当时我调试了很多aries.transaction.wrapper,但我记不清是什么原因遗漏了它。我认为背后的动机是commons dbcp是一个在以前的项目中对我有效的解决方案,而我无法修复aries.transaction.wrapper,即使在对它的代码进行了大量分析之后
请注意,MysqlDataSource不是连接池。它总是在您需要时返回一个新连接。它也没有启用XA。MysqlXADatasource启用了XA,因此您可能应该实例化该类中的对象。但是,XADataSource只负责为您返回XAConnections,而不负责登记它们。这就是ManagedConnectionPool可以提供帮助的地方。托管连接池执行以下操作:
- 使用自定义托管连接类包装所有提供的连接对象
- 在连接上调用close的情况下,如果存在正在进行的事务,则不会关闭该连接。它仅在事务提交或回滚完成时关闭(添加回池)
- 如果从池中查询连接,并且在同一事务中也提供了连接,那么将返回同一事务(这是一个困难的句子:)
有时JDBC驱动程序提供连接池甚至托管连接池,但是,最好只使用JDBC驱动程序来获得新的连接,并用第三方库包装它,该库在多个项目中进行了测试,并且确实有效。谢谢您,Balazs。我试过你的建议,到目前为止似乎有效。你认为你能解释一下为什么这个配置能解决这个问题吗?