无法让 Bitronix 在 Spring 引导项目中管理我的 datasource/transactions
Cannot make Bitronix manage my datasource/transactions in Spring Boot project
我已经尝试制作 JPAKnowledgeService
大约 3 天了,我几乎要放弃了,对于它 is/does 来说似乎配置和细节工作太多了。然而,
我最初有 ,添加后就消失了
java.naming.factory.initial=bitronix.tm.jndi.BitronixInitialContextFactory
进入我的 jndi.properties
文件,如答案所示。我终于能够创建一个 StatefulKnowledgeSession
,并认为工作结束了。但是在 drools 聊天中,同一个人建议我的事务可能是由 Hibernate 而不是 Bitronix 处理的,这可能使我的持久性完全非事务性。
而且我猜他是对的,因为每当我尝试将 Object
插入 Knowledge 会话并调用 fireAllRules
时,我都被困在:
executing transaction with 0 enlisted resource
其次是:
transaction timed out: a Bitronix Transaction with GTRID [3132372E302E312E310000000000AFB9D800000006], status=MARKED_ROLLBACK, 0 resource(s) enlisted (started Thu Jan 01 05:11:56 EET 1970)
之后我改变的是;我更新了我的 persistence.xml
如下:
<?xml version="1.0" encoding="UTF-8" ?>
<persistence 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_1_0.xsd" version="1.0">
<persistence-unit name="org.jbpm.persistence.jpa" transaction-type="JTA">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<jta-data-source>java:comp/env/jdbc/jbpm</jta-data-source>
<class>org.drools.persistence.info.SessionInfo</class>
<properties>
<property name="hibernate.jndi.class" value="bitronix.tm.jndi.BitronixInitialContextFactory"/>
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5InnoDBDialect"/>
<property name="hibernate.max_fetch_depth" value="3"/>
<property name="hibernate.hbm2ddl.auto" value="update" />
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.transaction.manager_lookup_class" value="org.hibernate.transaction.BTMTransactionManagerLookup" />
</properties>
</persistence-unit>
</persistence>
将此行添加到我的 application.properties
:
spring.datasource.jndi-name=java:comp/env/jdbc/jbpm
并按照 these instructions.
为嵌入式 tomcat 数据源指定了一个 jndi 名称
错误又回来了:
Caused by: java.lang.NullPointerException: null
at org.drools.persistence.jta.JtaTransactionManager.getStatus(JtaTransactionManager.java:273) ~[drools-persistence-jpa-6.5.0.Final.jar:6.5.0.Final]
at org.drools.persistence.jpa.AbstractPersistenceContextManager.getApplicationScopedEntityManager(AbstractPersistenceContextManager.java:78) ~[drools-persistence-jpa-6.5.0.Final.jar:6.5.0.Final]
at org.drools.persistence.jpa.JpaPersistenceContextManager.getApplicationScopedPersistenceContext(JpaPersistenceContextManager.java:55) ~[drools-persistence-jpa-6.5.0.Final.jar:6.5.0.Final]
at org.drools.persistence.SingleSessionCommandService.<init>(SingleSessionCommandService.java:103) ~[drools-persistence-jpa-6.5.0.Final.jar:6.5.0.Final]
... 43 common frames omitted
在数据库中创建了与 JPAKnowledgeService
相关的表,所以我猜我的 JNDI 注册成功了,但是我似乎无法找到 Bitronix 作为我的事务管理器,因为 JtaTransactionManager
似乎为空。我究竟做错了什么?我很沮丧,也很无能。
显然,我不必使用 Tomcat 将我的默认数据源注册为 JNDI,而是让 Bitronix 直接管理它,如下所示:
@Bean
public PoolingDataSource setupPoolingDataSource() {
PoolingDataSource pds = new PoolingDataSource();
pds.setUniqueName("jdbc/jbpm");
pds.setClassName("bitronix.tm.resource.jdbc.lrc.LrcXADataSource");
pds.setMaxPoolSize(50);
pds.setAllowLocalTransactions(true);
pds.getDriverProperties().put("user", "username");
pds.getDriverProperties().put("password", "password");
pds.getDriverProperties().put("url", "jdbc:mysql://localhost/databaseName?useUnicode=yes&characterEncoding=UTF-8&useSSL=false");
pds.getDriverProperties().put("driverClassName", "com.mysql.jdbc.Driver");
pds.init();
return pds;
}
并删除了这些内容:
@Bean
public TomcatEmbeddedServletContainerFactory tomcatFactory() {
return new TomcatEmbeddedServletContainerFactory() {
@Override
protected TomcatEmbeddedServletContainer getTomcatEmbeddedServletContainer(
Tomcat tomcat) {
tomcat.enableNaming();
return super.getTomcatEmbeddedServletContainer(tomcat);
}
@Override
protected void postProcessContext(Context context) {
ContextResource resource = new ContextResource();
resource.setName(name);
resource.setType(DataSource.class.getName());
resource.setProperty("url", "...");
resource.setProperty("username", "...");
resource.setProperty("password", "...");
resource.setProperty("driverClassName", "...");
resource.setProperty("factory", "org.apache.tomcat.jdbc.pool.DataSourceFactory");
context.getNamingResources().addResource(resource);
}
};
}
@Bean
public DataSource jndiDataSource() throws IllegalArgumentException, NamingException {
JndiObjectFactoryBean bean = new JndiObjectFactoryBean();
bean.setJndiName("...");
bean.setProxyInterface(DataSource.class);
bean.setLookupOnStartup(false);
bean.afterPropertiesSet();
return (DataSource)bean.getObject();
}
其他一切都保持不变并且有效!
我已经尝试制作 JPAKnowledgeService
大约 3 天了,我几乎要放弃了,对于它 is/does 来说似乎配置和细节工作太多了。然而,
我最初有
java.naming.factory.initial=bitronix.tm.jndi.BitronixInitialContextFactory
进入我的 jndi.properties
文件,如答案所示。我终于能够创建一个 StatefulKnowledgeSession
,并认为工作结束了。但是在 drools 聊天中,同一个人建议我的事务可能是由 Hibernate 而不是 Bitronix 处理的,这可能使我的持久性完全非事务性。
而且我猜他是对的,因为每当我尝试将 Object
插入 Knowledge 会话并调用 fireAllRules
时,我都被困在:
executing transaction with 0 enlisted resource
其次是:
transaction timed out: a Bitronix Transaction with GTRID [3132372E302E312E310000000000AFB9D800000006], status=MARKED_ROLLBACK, 0 resource(s) enlisted (started Thu Jan 01 05:11:56 EET 1970)
之后我改变的是;我更新了我的 persistence.xml
如下:
<?xml version="1.0" encoding="UTF-8" ?>
<persistence 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_1_0.xsd" version="1.0">
<persistence-unit name="org.jbpm.persistence.jpa" transaction-type="JTA">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<jta-data-source>java:comp/env/jdbc/jbpm</jta-data-source>
<class>org.drools.persistence.info.SessionInfo</class>
<properties>
<property name="hibernate.jndi.class" value="bitronix.tm.jndi.BitronixInitialContextFactory"/>
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5InnoDBDialect"/>
<property name="hibernate.max_fetch_depth" value="3"/>
<property name="hibernate.hbm2ddl.auto" value="update" />
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.transaction.manager_lookup_class" value="org.hibernate.transaction.BTMTransactionManagerLookup" />
</properties>
</persistence-unit>
</persistence>
将此行添加到我的 application.properties
:
spring.datasource.jndi-name=java:comp/env/jdbc/jbpm
并按照 these instructions.
为嵌入式 tomcat 数据源指定了一个 jndi 名称错误又回来了:
Caused by: java.lang.NullPointerException: null
at org.drools.persistence.jta.JtaTransactionManager.getStatus(JtaTransactionManager.java:273) ~[drools-persistence-jpa-6.5.0.Final.jar:6.5.0.Final]
at org.drools.persistence.jpa.AbstractPersistenceContextManager.getApplicationScopedEntityManager(AbstractPersistenceContextManager.java:78) ~[drools-persistence-jpa-6.5.0.Final.jar:6.5.0.Final]
at org.drools.persistence.jpa.JpaPersistenceContextManager.getApplicationScopedPersistenceContext(JpaPersistenceContextManager.java:55) ~[drools-persistence-jpa-6.5.0.Final.jar:6.5.0.Final]
at org.drools.persistence.SingleSessionCommandService.<init>(SingleSessionCommandService.java:103) ~[drools-persistence-jpa-6.5.0.Final.jar:6.5.0.Final]
... 43 common frames omitted
在数据库中创建了与 JPAKnowledgeService
相关的表,所以我猜我的 JNDI 注册成功了,但是我似乎无法找到 Bitronix 作为我的事务管理器,因为 JtaTransactionManager
似乎为空。我究竟做错了什么?我很沮丧,也很无能。
显然,我不必使用 Tomcat 将我的默认数据源注册为 JNDI,而是让 Bitronix 直接管理它,如下所示:
@Bean
public PoolingDataSource setupPoolingDataSource() {
PoolingDataSource pds = new PoolingDataSource();
pds.setUniqueName("jdbc/jbpm");
pds.setClassName("bitronix.tm.resource.jdbc.lrc.LrcXADataSource");
pds.setMaxPoolSize(50);
pds.setAllowLocalTransactions(true);
pds.getDriverProperties().put("user", "username");
pds.getDriverProperties().put("password", "password");
pds.getDriverProperties().put("url", "jdbc:mysql://localhost/databaseName?useUnicode=yes&characterEncoding=UTF-8&useSSL=false");
pds.getDriverProperties().put("driverClassName", "com.mysql.jdbc.Driver");
pds.init();
return pds;
}
并删除了这些内容:
@Bean
public TomcatEmbeddedServletContainerFactory tomcatFactory() {
return new TomcatEmbeddedServletContainerFactory() {
@Override
protected TomcatEmbeddedServletContainer getTomcatEmbeddedServletContainer(
Tomcat tomcat) {
tomcat.enableNaming();
return super.getTomcatEmbeddedServletContainer(tomcat);
}
@Override
protected void postProcessContext(Context context) {
ContextResource resource = new ContextResource();
resource.setName(name);
resource.setType(DataSource.class.getName());
resource.setProperty("url", "...");
resource.setProperty("username", "...");
resource.setProperty("password", "...");
resource.setProperty("driverClassName", "...");
resource.setProperty("factory", "org.apache.tomcat.jdbc.pool.DataSourceFactory");
context.getNamingResources().addResource(resource);
}
};
}
@Bean
public DataSource jndiDataSource() throws IllegalArgumentException, NamingException {
JndiObjectFactoryBean bean = new JndiObjectFactoryBean();
bean.setJndiName("...");
bean.setProxyInterface(DataSource.class);
bean.setLookupOnStartup(false);
bean.afterPropertiesSet();
return (DataSource)bean.getObject();
}
其他一切都保持不变并且有效!