Spring全局事务之JBOSS JTA实现Oracle、Ms SqlServer在同一事务中
来源:互联网 发布:手机版轰炸机软件 编辑:程序博客网 时间:2024/05/16 05:36
Spring全局事务之JBOSS JTA实现Oracle、Ms SqlServer在同一事务中
很久以来就一直知道,使用容器事务可以实现多个不同数据源处于同一事务中的功能。苦于没有时间和机会好好实验一把。今天机会难得,化了半天时间做了一个两个Oracle数据源和一个Ms Sql Server数据源在JBoss下的协同事务。下面简单说一下配置和实验情况。
第一、JBoss数据源配置
要使用JBoss的JTA,首先要做的就是配置链接各种数据源的XA类型的ds文件。
1、链接Oracle一的数据源,这是一个链接Oracle小型机的oracle-ds.xml 链接文件。配置如下:
<?xml version="1.0" encoding="UTF-8"?>
<!-- ===================================================================== -->
<!-- -->
<!-- JBoss Server Configuration -->
<!-- -->
<!-- ===================================================================== -->
<!-- $Id: oracle-xa-ds.xml 63175 2007-05-21 16:26:06Z rrajesh $ -->
<!-- ===================================================================== -->
<!-- ATTENTION: DO NOT FORGET TO SET Pad=true IN transaction-service.xml -->
<!-- ===================================================================== -->
<datasources>
<xa-datasource>
<jndi-name>XAOracleDS</jndi-name>
<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:@(DESCRIPTION =(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.10.243)(PORT = 1521))(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.10.244)(PORT = 1521))(LOAD_BALANCE = yes)(CONNECT_DATA =(SERVER = DEDICATED)(SERVICE_NAME = GBDATA)))</xa-datasource-property>
<xa-datasource-property name="User">abc</xa-datasource-property>
<xa-datasource-property name="Password">abc</xa-datasource-property>
<!-- Uses the pingDatabase method to check a connection is still valid before handing it out from the pool -->
<!--valid-connection-checker-class-name>org.jboss.resource.adapter.jdbc.vendor.OracleValidConnectionChecker</valid-connection-checker-class-name-->
<!-- Checks the Oracle error codes and messages for fatal errors -->
<exception-sorter-class-name>org.jboss.resource.adapter.jdbc.vendor.OracleExceptionSorter</exception-sorter-class-name>
<!-- Oracles XA datasource cannot reuse a connection outside a transaction once enlisted in a global transaction and vice-versa -->
<no-tx-separate-pools/>
<!-- corresponding type-mapping in the standardjbosscmp-jdbc.xml -->
<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> </datasources> 2、链接Oracle二的数据源,这是一个链接Oracle测试服务器的testoracle-xa-ds.xml链接文件。配置如下 <?xml version="1.0" encoding="UTF-8"?> <!-- ===================================================================== --> <!-- $Id: oracle-xa-ds.xml 63175 2007-05-21 16:26:06Z rrajesh $ --> <!-- ===================================================================== --> <datasources> <!-- corresponding type-mapping in the standardjbosscmp-jdbc.xml --> <mbean code="org.jboss.resource.adapter.jdbc.vendor.OracleXAExceptionFormatter" <depends optional-attribute-name="TransactionManagerService">jboss:service=TransactionManager</depends> </datasources> <?xml version="1.0" encoding="UTF-8"?> <!-- ===================================================================== --> <!-- $Id: mssql-xa-ds.xml 63175 2007-05-21 16:26:06Z rrajesh $ --> <!-- corresponding type-mapping in the standardjbosscmp-jdbc.xml --> </datasources> 第二、各种数据源的驱动配置。 Oracle的驱动如下: ojdbc14.jar、ojdbc14_g.jar Sql Server的驱动如下: 要使用Sql Server2005的XA事务,还需要满足以下条件: 1、Sql Server2005运行在Window2000或者Window2003环境下 2、在数据库服务器上运行MSDTC,并且启用XA事务。(在组件服务-->我的电脑,右键属性,可以看到MSDTCx项目) 3、在数据库的Master库中创建扩展存储过程、根据机器的不同把sqljdbc_xa.dll文件拷贝到sql server的Binn目录下,并在数据库中设置相应权限,详细过程如下: 1. 将 sqljdbc_xa.dll 从该目录复制到将参与分布式事务的每台 SQL Server 计算机的 Binn 目录下。 注意: 如果使用 32 位处理器,请使用文件夹 x86 中的 sqljdbc_xa.dll。 如果使用 64 位 x64 处理器,请使用文件夹 x64 中的 sqljdbc_xa.dll。 2. 在将要参与分布式事务的每台 SQL Server 计算机上执行数据库脚本 xa_install.sql。 3. 要授予特定用户 在EJB中使用单例模型创建ApplicationContext对象实例 public final class AppBeanFactory { private static ApplicationContext factory=null; private AppBeanFactory() {} public static synchronized ApplicationContext getInstance() { if(factory == null) { factory=new ClassPathXmlApplicationContext("conf/applicationContext.xml"); <?xml version="1.0" encoding="UTF-8"?> <beans <bean id="wmsdstestjndi" class="org.springframework.jndi.JndiObjectFactoryBean"> </bean> <!-- 定义事务管理器 --> <bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager"/> <tx:annotation-driven transaction-manager="transactionManager"/> <!-- 定义各个数据源对应的jdbcTemplace --> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> </beans> 在具体的EJB中使用如下样式调用: public class OrderForm implements IOrderForm{ @Transactional(readOnly=false, propagation = Propagation.REQUIRED,rollbackFor=Exception.class) public void InsertOrderForm() throws Exception { this.jdbc.execute("Insert Into OrderFormTest(OrderFormID,FormDate)values('ODZB001',to_date('2009-11-02','YYYY-MM-DD'))"); JdbcTemplate myjdbc=(JdbcTemplate)AppBeanFactory.getInstance().getBean("jdbcTemplateebdata"); //Ms Sql Server throw new Exception("Error occured in OrderFormST"); // 添加某个商品信息 // 获得客户购买的所有商品的纱衔泥 public class ShoppingCartBean implements ShoppingCart { public void addCommodity(String value) { IOrderForm of=(IOrderForm)AppBeanFactory.getInstance().getBean("OrderForm"); try {
</mbean>
<!-- -->
<!-- JBoss Server Configuration -->
<!-- -->
<!-- ===================================================================== -->
<!-- ATTENTION: DO NOT FORGET TO SET Pad=true IN transaction-service.xml -->
<!-- ===================================================================== -->
<xa-datasource>
<jndi-name>XAOracleDSTest</jndi-name>
<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:@(DESCRIPTION =(ADDRESS_LIST =(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.10.48)(PORT = 1521)))(CONNECT_DATA =(SID = testdb)))</xa-datasource-property>
<xa-datasource-property name="User">aaa</xa-datasource-property>
<xa-datasource-property name="Password">aaa</xa-datasource-property>
<!-- Uses the pingDatabase method to check a connection is still valid before handing it out from the pool -->
<!--valid-connection-checker-class-name>org.jboss.resource.adapter.jdbc.vendor.OracleValidConnectionChecker</valid-connection-checker-class-name-->
<!-- Checks the Oracle error codes and messages for fatal errors -->
<exception-sorter-class-name>org.jboss.resource.adapter.jdbc.vendor.OracleExceptionSorter</exception-sorter-class-name>
<!-- Oracles XA datasource cannot reuse a connection outside a transaction once enlisted in a global transaction and vice-versa -->
<no-tx-separate-pools/>
<metadata>
<type-mapping>Oracle9i</type-mapping>
</metadata>
</xa-datasource>
name="jboss.jca:service=OracleXAExceptionFormatterTest">
</mbean>
3、链接Sql Server的数据源,mssql-xa-ds.xml配置如下
<!-- -->
<!-- JBoss Server Configuration -->
<!-- -->
<!-- ===================================================================== -->
<!-- ==================================================================== -->
<!-- ConnectionManager setup for xa Microsoft SQL Server 2005, using -->
<!-- Microsoft's JDBC driver. -->
<!-- Thanks to Benjamin Geer <benjamin.geer@misys.com> -->
<!-- Be sure to set the JndiName property to the name you want to look up -->
<!-- the datasource under and set the location of your database in -->
<!-- the xa-datasource-property section. -->
<!-- Further information about the Microsoft JDBC Driver version 1.1 -->
<!-- can be found here: -->
<!-- http://msdn2.microsoft.com/en-us/library/aa496082.aspx -->
<!-- ==================================================================== -->
<datasources>
<xa-datasource>
<jndi-name>MSSQLXADS</jndi-name>
<track-connection-by-tx/>
<isSameRM-override-value>false</isSameRM-override-value>
<xa-datasource-class>com.microsoft.sqlserver.jdbc.SQLServerXADataSource</xa-datasource-class>
<xa-datasource-property name="ServerName">192.168.10.15</xa-datasource-property>
<xa-datasource-property name="DatabaseName">TestData</xa-datasource-property>
<xa-datasource-property name="SelectMethod">cursor</xa-datasource-property>
<!-- not sure if these should be here-->
<user-name>SM</user-name>
<password>123123</password>
<metadata>
<type-mapping>MS SQLSERVER2000</type-mapping>
</metadata>
</xa-datasource>
配置好三个数据源后,放到JBoss目录下:D:/jboss-4.2.2.GA/server/default/deploy
链接Oracle 和Sql Server的驱动,需要放到JBoss的Lib目录中
msbase.jar、mssqlserver.jar、msutil.jar、sqljdbc.jar(Microsoft SQL Server 2005 JDBC Driver,在此Jar中包含了XA事务所必须的com.microsoft.sqlserver.jdbc.SQLServerXADataSource.class)
使用 Microsoft SQL Server 2005 JDBC 驱动程序参与分布式事务的权限,请将该用户添加到 SqlJDBCXAUser 角色中。使用什么用户连接Sql Server就需要把该用户加入到SqlJDBCXAUser 角色中
第三、在JBOSS的EJB中使用Spring
}
}
}
applicationContext.xml的详细配置如下:
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
<property name="jndiName" value="java:XAOracleDSTest"></property>
<!-- JNDI获取真实数据源 -->
<bean id="wmsdsjndi" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="java:XAOracleDS"></property>
</bean>
<!-- JNDI获取Sql Server数据源 -->
<bean id="sqldsjndi" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="java:MSSQLXADS"></property>
</bean>
<property name="dataSource">
<ref bean="wmsdstestjndi" />
</property>
</bean>
<bean id="jdbcTemplateebdata" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource">
<ref bean="wmsdsjndi" />
</property>
</bean>
<bean id="jdbcTemplatesql" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource">
<ref bean="sqldsjndi" />
</property>
</bean>
//Oracle一、
JdbcTemplate myjdbc=(JdbcTemplate)AppBeanFactory.getInstance().getBean("jdbcTemplate");
//Oracle 二
myjdbc.execute("Insert into OrderFormSTTest(OrderFormID,ProductID,Qty)values('ODZB001','000001',10)");
myjdbc=(JdbcTemplate)AppBeanFactory.getInstance().getBean("jdbcTemplatesql");
myjdbc.execute("Insert into OrderFormSTTest(OrderFormID,ProductID,Qty)values('ODZB001','000001',10)");
}
}
第四、把OrderForm类封装进EJB中、以便实现远程调用
1、远程接口
@Remote
public interface ShoppingCart {
public void addCommodity (String value);
public List<String> getCommodity();
}
2、远程接口实现
@Stateful
of.InsertOrderForm();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
第五、客户端实现EJB调用
InitialContext ic = new InitialContext();
ShoppingCart shoppingCart = (ShoppingCart)ic.lookup("ShoppingCartBean/remote");
shoppingCart.addCommodity("自行车");
- Spring全局事务之JBOSS JTA实现Oracle、Ms SqlServer在同一事务中
- Spring全局事务之JTA+Atomikos
- Spring全局事务之JTA+Atomikos
- JBoss+Oracle+JTA配置分布式事务
- Spring+JTA实现分布式事务
- 在Spring中使用JTA事务管理【两个数据库实现事务控制】
- Spring在tomcat下使用JTA事务
- Spring+iBatis+Atomikos实现JTA事务
- Spring+iBatis+Atomikos实现JTA事务
- Spring+iBatis+Atomikos实现JTA事务
- Spring+iBatis+Atomikos实现JTA事务
- Spring+iBatis+Atomikos实现JTA事务
- Spring+iBatis+Atomikos实现JTA事务
- spring+mybatis+atomikos 实现JTA事务
- Spring+iBatis+JOTM实现JTA事务
- Spring+iBatis+Atomikos实现JTA事务
- Spring+iBatis+Atomikos实现JTA事务
- 使用JTA做全局事务
- 基于ARM含SD控制器的SD卡的SDIO模式驱动解析
- oracle中in,not in和exists,not exists之间的区别
- log4j 發郵件 多個 logger
- 使用rsync进行CentOS服务器之间的目录同步
- 虚析构函数
- Spring全局事务之JBOSS JTA实现Oracle、Ms SqlServer在同一事务中
- 父母的爱
- python中的exec 函数
- ACS动画下载地址和MASH下载地址
- [双语阅读]为防流感 意大利人发明自动圣水机
- XML学习(C#创建XML)
- LVM应用之变更/data 的大小
- RAISE_APPLICATION_ERROR
- MFC扩展DLL 小结