使用 JNDI 查找 XADatasource 时出现异常



>我已经在wildlfy服务器中配置了XADatasource,因为我需要使用JTA事务,并且需要使用Atomikos实现使用JTATransactionManager管理多个数据库。我在查找并使用弹簧启动构建AtomikosDatasource时得到下面的ClassCastException。似乎JNDI查找总是返回WildflyDatasource,并且它没有实现XADatasource。请建议我如何在我们查找时获取XADatasource而不是WildflyDatasource,或者从WildlfyDatasource转换为XADatasource。

原因:java.lang.ClassCastException: org.jboss.as.connector.subsystems.datasources.WildFlyDataSource 不能强制转换为 javax.sql.XADataSource

下面是查找数据源和创建 AtomikosDataSourceBean 的代码片段

*@Bean(name = "customerDataSource", initMethod = "init", destroyMethod = "close")
@Primary
public DataSource customerDataSource() throws NamingException {     
JndiDataSourceLookup dataSourceLookup = new JndiDataSourceLookup();
XADataSource mysqlXaDataSource =  (XADataSource) dataSourceLookup.getDataSource("java:/jdbc/atomikos_one");
AtomikosDataSourceBean xaDataSource = new AtomikosDataSourceBean();
xaDataSource.setXaDataSource(mysqlXaDataSource);        
xaDataSource.setUniqueResourceName("xads1");
return xaDataSource;
}*

以下是 Wildfly 10.1.0.Final 中的数据源配置

<xa-datasource jndi-name="java:/jdbc/atomikos_one" pool-name="atomikos_one" enabled="true" use-ccm="true">
<xa-datasource-property name="ServerName">
localhost
</xa-datasource-property>
<xa-datasource-property name="DatabaseName">
atomikos_one
</xa-datasource-property>
<driver>mysql</driver>
<xa-pool>
<min-pool-size>5</min-pool-size>
<max-pool-size>100</max-pool-size>
<use-strict-min>true</use-strict-min>
<wrap-xa-resource>false</wrap-xa-resource>
</xa-pool>
<security>
<user-name>root</user-name>
<password>password</password>
</security>
<validation>
<valid-connection-checker class-name="org.jboss.jca.adapters.jdbc.extensions.mysql.MySQLValidConnectionChecker"/>
<background-validation>true</background-validation>
<exception-sorter class-name="org.jboss.jca.adapters.jdbc.extensions.mysql.MySQLExceptionSorter"/>
</validation>
</xa-datasource>
<driver name="mysql" module="com.mysql">
<driver-class>com.mysql.jdbc.Driver</driver-class>
<xa-datasource-class>com.mysql.jdbc.jdbc2.optional.MysqlXADataSource</xa-datasource-class>
</driver>

让它工作了。 我已经意识到内置的JTA TransactionManagers已经在应用程序服务器中可用并使用它,而不是使用它的自定义实现(Atomikos(。 对于这个问题的答案,我们仍然可以在应用程序服务器中配置 XADatasoruce 并使用 JNDI 进行查找,并将其类型转换为普通数据源并将其注入 EntityManager。 mysqlXaDataSource 仍将保存对 XA 数据源的引用,即使类型是 Datasource。

The below is the snippet to show how is it working now.

@Bean(name = "customerDataSource", initMethod = "init", destroyMethod = "close")
@Primary
public DataSource customerDataSource() throws NamingException {     
JndiDataSourceLookup dataSourceLookup = new JndiDataSourceLookup();
DataSource mysqlXaDataSource =  (DataSource ) dataSourceLookup.getDataSource("java:/jdbc/jta_datasource_one");
return mysqlXaDataSource;
}

LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setJtaDataSource(customerDataSource());

最新更新