我有一个OSGi包,需要在数据库中保存数据。如上所述in a previous stackoverflow question我发现为了使事务按预期工作,我需要使用XADataSource连接到数据库。但是当我这样做时,我发现我的应用程序打开的数据库连接永远不会关闭,这当然会导致数据库在一段时间后无法再接受任何连接。
我的设置如下:
我有一个创建数据源的bundle,它只包含一个带有以下内容的blueprint.xml文件
<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>
我指定我的服务方法应该在我的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中使用捆绑包进行部署,使用Aries和OpenJPA进行持久化,同时我还部署了Aries事务包装器包(org.apache.aries.transaction.wrappers),以便使用事务管理器登记我的XA资源。
我的配置中缺少哪些想法?
修改 经过一些搜索,我发现this DBCP issue表明我遇到的问题是DBCP与MySQL的错误。但是,我对如何使用OpenJPA可以使用的其他连接池实现替换DBCP感到茫然。任何建议都非常受欢迎。
答案 0 :(得分:1)
我使用commons-dbcp来建立一个连接池,该连接池还使用以下配置登记XA Connections:
<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方法就在那里,所以当蓝图容器停止时,连接池将被关闭。
修改强>
1 - 2年前,我遇到了同样的问题但是使用了PostgreSQL。我当时调试了aries.transaction.wrapper很多,但我不记得究竟为什么我把它遗漏了。我认为动机是背后的共同点 - dbcp是一个在以前的项目中对我有用的解决方案,而我无法修复aries.transaction.wrapper,即使在分析它的代码之后也是如此。请注意,MysqlDataSource不是连接池。它总是在您需要时提供新连接。它也没有启用XA。 MysqlXADatasource已启用XA,因此您可能应该从该类实例化一个对象。但是,XADataSource只负责为您提供XAConnections,而不是为了获取它们。这是ManagedConnectionPool可以提供帮助的地方。托管连接池执行以下操作:
有时JDBC驱动程序提供连接池甚至托管连接池,但是,最好只使用JDBC驱动程序来获取新连接,并将其包装在第三方库中,该库已在多个项目中进行测试并确实可以正常工作。