分布式跨数据库的事务处理要用到
oracle.jdbc.xa.client.OracleXADataSource
类型的数据源。我们要把数据源注册到
jndi
服务上去。注册的
xml
文件名称为
oracle-xa-ds.xml:
文件格式如下
:
<?
xml version="1.0" encoding="UTF-8"
?>
< datasources >
< xa-datasource >
< jndi-name > myDs </ jndi-name >
<! —把数据源注册为全局的,缺省的情况下为true-- >
< use-java-context > false </ use-java-context >
< track-connection-by-tx />
< isSameRM-override-value > false </ isSameRM-override-value > < xa-datasource-class > oracle.jdbc.xa.client.OracleXADataSource </ xa-datasource-class >
< xa-datasource-property name ="URL" > jdbc:oracle:thin:@databaseUrl:orcl </ xa-datasource-property >
< xa-datasource-property name ="User" > user </ xa-datasource-property >
< xa-datasource-property name ="Password" > passwrod </ xa-datasource-property >
< metadata >
< type-mapping > Oracle9i </ type-mapping >
</ metadata >
</ xa-datasource >
< xa-datasource >
< jndi-name > myDs1 </ jndi-name >
< use-java-context > false </ use-java-context >
< track-connection-by-tx />
< isSameRM-override-value > false </ isSameRM-override-value > < xa-datasource-class > oracle.jdbc.xa.client.OracleXADataSource </ xa-datasource-class >
< xa-datasource-property name ="URL" > jdbc:oracle:thin:@databaseUrl:orcl </ xa-datasource-property >
< xa-datasource-property name ="User" > user </ xa-datasource-property >
< xa-datasource-property name ="Password" > password </ xa-datasource-property >
< exception-sorter-class-name > org.jboss.resource.adapter.jdbc.vendor.OracleExceptionSorter </ exception-sorter-class-name >
< no-tx-separate-pools />
< metadata >
< type-mapping > Oracle9i </ type-mapping >
</ metadata >
</ xa-datasource >
< mbean code ="org.jboss.resource.adapter.jdbc.vendor.OracleXAExceptionFormatter"
name ="jboss.jca:service=OracleXAExceptionFormatter" >
< depends optional-attribute-name ="TransactionManagerService" > jboss:service=TransactionManager </ depends >
</ mbean >
</ datasources >
< datasources >
< xa-datasource >
< jndi-name > myDs </ jndi-name >
<! —把数据源注册为全局的,缺省的情况下为true-- >
< use-java-context > false </ use-java-context >
< track-connection-by-tx />
< isSameRM-override-value > false </ isSameRM-override-value > < xa-datasource-class > oracle.jdbc.xa.client.OracleXADataSource </ xa-datasource-class >
< xa-datasource-property name ="URL" > jdbc:oracle:thin:@databaseUrl:orcl </ xa-datasource-property >
< xa-datasource-property name ="User" > user </ xa-datasource-property >
< xa-datasource-property name ="Password" > passwrod </ xa-datasource-property >
< metadata >
< type-mapping > Oracle9i </ type-mapping >
</ metadata >
</ xa-datasource >
< xa-datasource >
< jndi-name > myDs1 </ jndi-name >
< use-java-context > false </ use-java-context >
< track-connection-by-tx />
< isSameRM-override-value > false </ isSameRM-override-value > < xa-datasource-class > oracle.jdbc.xa.client.OracleXADataSource </ xa-datasource-class >
< xa-datasource-property name ="URL" > jdbc:oracle:thin:@databaseUrl:orcl </ xa-datasource-property >
< xa-datasource-property name ="User" > user </ xa-datasource-property >
< xa-datasource-property name ="Password" > password </ xa-datasource-property >
< exception-sorter-class-name > org.jboss.resource.adapter.jdbc.vendor.OracleExceptionSorter </ exception-sorter-class-name >
< no-tx-separate-pools />
< metadata >
< type-mapping > Oracle9i </ type-mapping >
</ metadata >
</ xa-datasource >
< mbean code ="org.jboss.resource.adapter.jdbc.vendor.OracleXAExceptionFormatter"
name ="jboss.jca:service=OracleXAExceptionFormatter" >
< depends optional-attribute-name ="TransactionManagerService" > jboss:service=TransactionManager </ depends >
</ mbean >
</ datasources >
可直接把该文件放置到
deploy
目录下面。
Jboss
中带有示例程序目录位置为
/docs/examples/jca
,
把上面的
xml
文件部署完毕后还有一个地方需要修改那就是
/server/default/conf
目录下的
jboss-service.xml
配置文件中有:
<!--
The configurable Xid factory. For use with Oracle, set pad to true
-->
< mbean code ="org.jboss.tm.XidFactory"
name ="jboss:service=XidFactory" >
<!-- attribute name="Pad">true</attribute -->
</ mbean >
< mbean code ="org.jboss.tm.XidFactory"
name ="jboss:service=XidFactory" >
<!-- attribute name="Pad">true</attribute -->
</ mbean >
如果你使用的
jdbc
驱动
version>=10.0
此处可以不修改,如果
jdbc
驱动
version<10.0,
那就要把
pad
属性值设置为
true;
这样你就可以写代码编辑分布式事务处理了。
首先要设置上下文属性值:
UserTransaction tx
=
null
;
Properties props = new Properties();
props.setProperty(Context.INITIAL_CONTEXT_FACTORY, ”org.jnp.interfaces.NamingContextFactory”);
props.setProperty(Context.PROVIDER_URL, ”jnp: // localhost:1099”);
props.setProperty(Context.URL_PKG_PREFIXES, “org.jboss.naming:org.jnp.interfaces”);
InitialContext ctx = new InitialContext(props);
Tx = (UserTransaction)ctx.lookup(“UserTransaction”);
Properties props = new Properties();
props.setProperty(Context.INITIAL_CONTEXT_FACTORY, ”org.jnp.interfaces.NamingContextFactory”);
props.setProperty(Context.PROVIDER_URL, ”jnp: // localhost:1099”);
props.setProperty(Context.URL_PKG_PREFIXES, “org.jboss.naming:org.jnp.interfaces”);
InitialContext ctx = new InitialContext(props);
Tx = (UserTransaction)ctx.lookup(“UserTransaction”);
运行上面这段代码你可能会得到这样的异常:
Java.lang.RuntimeException: UT factory lookup failed
这也涉及到你所使用的
jboss
版本的问题:
Version>=4.0.2:
就使用
org.jboss.naming.NamingContextFactory
来代替
org.jnp.interfaces.NamingContextFactory.
Version<4.0.2:
就使用
jboss
自带的
jndi.properties
文件进行配置。这样就可以进行分布式的事务处理了。
注意:
UserTransaction
中不能再嵌套其他的任何事务,否则会抛出异常。
Jta.jar
包要特别留意,如果按照以上配置仍不能运行,那就把环境中存在的
jta.jar
包删除。该事务管理的实现对上下文环境要求较高,环境中不要引入没有用处的
jar
包,否则可能会引起运行不成功!