﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-黑咖啡-文章分类-JTA</title><link>http://www.blogjava.net/kyleYang/category/43031.html</link><description>每个人都依靠自己的知识和认识，却又被其所束缚，还将这些称为现实，但是知识和认识是非常暧昧的东西，那个现实也许不过只是幻觉。人们都活在自我意识之中。</description><language>zh-cn</language><lastBuildDate>Wed, 09 Dec 2009 19:31:35 GMT</lastBuildDate><pubDate>Wed, 09 Dec 2009 19:31:35 GMT</pubDate><ttl>60</ttl><item><title>Spring JTA 事务小记</title><link>http://www.blogjava.net/kyleYang/articles/305314.html</link><dc:creator>飞熊</dc:creator><author>飞熊</author><pubDate>Wed, 09 Dec 2009 09:29:00 GMT</pubDate><guid>http://www.blogjava.net/kyleYang/articles/305314.html</guid><wfw:comment>http://www.blogjava.net/kyleYang/comments/305314.html</wfw:comment><comments>http://www.blogjava.net/kyleYang/articles/305314.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/kyleYang/comments/commentRss/305314.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/kyleYang/services/trackbacks/305314.html</trackback:ping><description><![CDATA[实验一：MySQL 5.0 <br />采用atomikos的jta事务（要感谢 http://andyao.javaeye.com/） <br />&lt;?xml version="1.0" encoding="UTF-8"?&gt; <br />&lt;beans xmlns="http://www.springframework.org/schema/beans" <br />xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" <br />xmlns:tx="http://www.springframework.org/schema/tx" <br />xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/<span class="hilite1"><font style="BACKGROUND-COLOR: #ffff00">spring</font></span>-beans-2.0.xsd <br />           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/<span class="hilite1"><font style="BACKGROUND-COLOR: #ffff00">spring</font></span>-aop-2.0.xsd <br />           http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/<span class="hilite1"><font style="BACKGROUND-COLOR: #ffff00">spring</font></span>-tx-2.0.xsd"&gt; <br /><br />&lt;bean id="dataSource" class="com.atomikos.jdbc.SimpleDataSourceBean" <br />init-method="init" destroy-method="close"&gt; <br />&lt;property name="uniqueResourceName"&gt; <br />&lt;value&gt;mysql/main&lt;/value&gt; <br />&lt;/property&gt; <br />&lt;property name="xaDataSourceClassName"&gt; <br />&lt;!--使用Mysql XADataSource(mysql&gt;=5.0, Connector/J&gt;=5.0才可以支持XADatasource)--&gt; <br />&lt;value&gt;com.mysql.jdbc.jdbc2.optional.MysqlXADataSource&lt;/value&gt; <br />&lt;/property&gt; <br />&lt;property name="xaDataSourceProperties"&gt; <br />&lt;value&gt;URL=jdbc:mysql://localhost:3306/crm?useUnicode=true&amp;amp;characterEncoding=UTF-8;user=root;password=root&lt;/value&gt; <br />&lt;/property&gt; <br />&lt;property name="exclusiveConnectionMode"&gt; <br />&lt;value&gt;true&lt;/value&gt; <br />&lt;/property&gt; <br />&lt;property name="connectionPoolSize"&gt; <br />&lt;value&gt;3&lt;/value&gt; <br />&lt;/property&gt; <br />&lt;property name="validatingQuery"&gt; <br />&lt;value&gt;SELECT 1&lt;/value&gt; <br />&lt;/property&gt; <br />&lt;/bean&gt; <br />&lt;!-- 第二个数据库 --&gt; <br />&lt;bean id="dataSourceB" class="com.atomikos.jdbc.SimpleDataSourceBean" <br />init-method="init" destroy-method="close"&gt; <br />&lt;property name="uniqueResourceName"&gt; <br />&lt;value&gt;mysql/news&lt;/value&gt; <br />&lt;/property&gt; <br />&lt;property name="xaDataSourceClassName"&gt; <br />&lt;!-- <br />使用Mysql XADataSource(mysql&gt;=5.0, Connector/J&gt;=5.0才可以支持XADatasource) <br />--&gt; <br />&lt;value&gt;com.mysql.jdbc.jdbc2.optional.MysqlXADataSource&lt;/value&gt; <br />&lt;/property&gt; <br />&lt;property name="xaDataSourceProperties"&gt; <br />&lt;value&gt;URL=jdbc:mysql://localhost:3306/crm2?useUnicode=true&amp;amp;characterEncoding=UTF-8;user=root;password=root&lt;/value&gt; <br />&lt;/property&gt; <br />&lt;property name="exclusiveConnectionMode"&gt; <br />&lt;value&gt;true&lt;/value&gt; <br />&lt;/property&gt; <br />&lt;property name="connectionPoolSize"&gt; <br />&lt;value&gt;3&lt;/value&gt; <br />&lt;/property&gt; <br />&lt;property name="validatingQuery"&gt; <br />&lt;value&gt;SELECT 1&lt;/value&gt; <br />&lt;/property&gt; <br />&lt;/bean&gt; <br /><br />&lt;bean id="lobHandler" class="org.springframework.jdbc.support.lob.DefaultLobHandler" /&gt; <br /><br />&lt;!-- 第一个数据库的sqlMapClient --&gt; <br />&lt;bean id="sqlMapClient1" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean"&gt; <br />&lt;property name="configLocation"&gt; <br />&lt;!-- 包含第一个数据库表的map --&gt; <br />&lt;value&gt;classpath:SqlMapConfig.xml&lt;/value&gt; <br />&lt;/property&gt; <br />&lt;property name="dataSource" ref="dataSource" /&gt; <br />&lt;property name="lobHandler" ref="lobHandler" /&gt; <br />&lt;/bean&gt; <br />&lt;!-- 第二个数据库的sqlMapClient --&gt; <br />&lt;bean id="sqlMapClient2" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean"&gt; <br />&lt;property name="configLocation"&gt; <br />&lt;!-- 包含第一个数据库表的map --&gt; <br />&lt;value&gt;classpath:SqlMapConfig2.xml&lt;/value&gt; <br />&lt;/property&gt; <br />&lt;property name="dataSource" ref="dataSourceB" /&gt; <br />&lt;property name="lobHandler" ref="lobHandler" /&gt; <br />&lt;/bean&gt; <br /><br />&lt;!-- Optional: add a log administrator --&gt; <br />&lt;bean id="localLogAdministrator" <br />class="com.atomikos.icatch.admin.imp.LocalLogAdministrator"/&gt; <br /><br />&lt;bean id="userTransactionService" <br />  class="com.atomikos.icatch.config.UserTransactionServiceImp" <br />  init-method="init" destroy-method="shutdownForce"&gt; <br />    &lt;constructor-arg&gt; <br />        &lt;!-- IMPORTANT: specify all Atomikos properties here --&gt; <br />        &lt;props&gt; <br />            &lt;prop key="com.atomikos.icatch.service"&gt;com.atomikos.icatch.standalone.UserTransactionServiceFactory&lt;/prop&gt; <br />        &lt;/props&gt; <br />    &lt;/constructor-arg&gt; <br />    &lt;property name="initialLogAdministrators"&gt; <br />        &lt;list&gt; <br />            &lt;ref bean="localLogAdministrator"/&gt; <br />        &lt;/list&gt; <br />    &lt;/property&gt; <br />&lt;/bean&gt; <br />&lt;!--Construct Atomikos UserTransactionManager,needed to configure <span class="hilite1"><font style="BACKGROUND-COLOR: #ffff00">Spring</font></span> --&gt; <br />&lt;bean id="AtomikosTransactionManager" <br />      class="com.atomikos.icatch.jta.UserTransactionManager" <br />      init-method="init" destroy-method="close" <br />      depends-on="userTransactionService"&gt; <br />   &lt;!--when close is called,should we force transactions to terminate or not?--&gt; <br />   &lt;property name="forceShutdown" value="false" /&gt; <br />&lt;/bean&gt; <br />   &lt;!--Also use Atomikos UserTransactionImp, needed to configure <span class="hilite1"><font style="BACKGROUND-COLOR: #ffff00">Spring</font></span>--&gt; <br />&lt;bean id="AtomikosUserTransaction" <br />      class="com.atomikos.icatch.jta.UserTransactionImp"  <br />      depends-on="userTransactionService"&gt; <br />   &lt;property name="transactionTimeout" value="300" /&gt; <br />&lt;/bean&gt; <br />   &lt;!-- Configure the <span class="hilite1"><font style="BACKGROUND-COLOR: #ffff00">Spring</font></span> framework to use JTA transactions from Atomikos --&gt; <br />&lt;bean id="JtaTransactionManager" <br />      class="org.springframework.transaction.jta.JtaTransactionManager" <br />      depends-on="userTransactionService"&gt; <br />   &lt;property name="transactionManager" ref="AtomikosTransactionManager" /&gt; <br />   &lt;property name="userTransaction" ref="AtomikosUserTransaction" /&gt; <br />&lt;/bean&gt; <br /><br />&lt;bean id="user1Dao" class="com.crm.code.dao.impl.User1DaoImpl"&gt; <br />&lt;property name="sqlMapClient"&gt; <br />&lt;ref bean="sqlMapClient1"/&gt; <br />&lt;/property&gt; <br />&lt;/bean&gt; <br />&lt;bean id="user2Dao" class="com.crm.code.dao.impl.User2DaoImpl"&gt; <br />&lt;property name="sqlMapClient"&gt; <br />&lt;ref bean="sqlMapClient2"/&gt; <br />&lt;/property&gt; <br />&lt;/bean&gt; <br />&lt;bean id="user12Service" class="com.crm.code.service.impl.User12ServiceImpl"&gt; <br />&lt;property name="user1Dao"&gt; <br />&lt;ref bean="user1Dao" /&gt; <br />&lt;/property&gt; <br />&lt;property name="user2Dao"&gt; <br />&lt;ref bean="user2Dao" /&gt; <br />&lt;/property&gt; <br />&lt;/bean&gt; <br /><br />&lt;/beans&gt; <br />这样是成功的 可是切换oracle9i时悲剧发生了 <br />--- Cause: com.atomikos.datasource.ResourceException: resume for XID oracle.jdbc.xa.OracleXid@145f939 raised -3: the XA resource detected an internal error <br />Caused by: com.ibatis.common.jdbc.exception.NestedSQLException:   <br />--- The error occurred in ibatis/Product1.xml.  <br />--- The error occurred while executing update.  <br />--- Check the          insert into boss_product     (PROD_ID,  PARENT_ID,  APP_ID,  PROD_NAME,  PROD_CODE,  DEFAULT_VER_PROD_ID,  DATA_PATH,  GMT_CREATED,  GMT_MODIFIED,  CREATOR,  MODIFIER,  IS_DELETED)      values     (seq_boss_product.nextval,      1,      88,      ?,      ?,      10,      'aaa',      sysdate,      sysdate,      'aavv',      'aacb',      'n')        .  <br /><br />官方说oracle连接问题 哎。。。无语了 <br />换了一种JTA事务机制 通过JOTM <br />&lt;?xml version="1.0" encoding="UTF-8"?&gt; <br />&lt;beans xmlns="http://www.springframework.org/schema/beans" <br />xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" <br />xmlns:tx="http://www.springframework.org/schema/tx" <br />xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/<span class="hilite1"><font style="BACKGROUND-COLOR: #ffff00">spring</font></span>-beans-2.0.xsd <br />           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/<span class="hilite1"><font style="BACKGROUND-COLOR: #ffff00">spring</font></span>-aop-2.0.xsd <br />           http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/<span class="hilite1"><font style="BACKGROUND-COLOR: #ffff00">spring</font></span>-tx-2.0.xsd"&gt; <br />           <br />   &lt;bean id="jotm" class="org.springframework.transaction.jta.JotmFactoryBean"/&gt;    <br />   &lt;bean id="txManager" class="org.springframework.transaction.jta.JtaTransactionManager"&gt;  <br />         &lt;property name="userTransaction" ref="jotm"/&gt; <br />   &lt;/bean&gt;           <br />    <br />    &lt;bean id="dataSourceA" class="org.enhydra.jdbc.pool.StandardXAPoolDataSource"  <br />    destroy-method="shutdown"&gt;  <br />        &lt;property name="dataSource"&gt; <br />             &lt;bean class="org.enhydra.jdbc.standard.StandardXADataSource" destroy-method="shutdown"&gt;  <br />                 &lt;property name="transactionManager" ref="jotm"/&gt;  <br />                 &lt;property name="driverName" value="oracle.jdbc.driver.OracleDriver"/&gt;  <br />                 &lt;property name="url" value="jdbc:oracle:thin:@10.2.224.44:1521:trade"/&gt;  <br />             &lt;/bean&gt;  <br />         &lt;/property&gt;  <br />         &lt;property name="user" value="crm_aep"/&gt;  <br />         &lt;property name="password" value="crm_aep"/&gt;  <br />     &lt;/bean&gt;  <br /><br />    &lt;bean id="dataSourceB" class="org.enhydra.jdbc.pool.StandardXAPoolDataSource"  <br />    destroy-method="shutdown"&gt;  <br />        &lt;property name="dataSource"&gt; <br />             &lt;bean class="org.enhydra.jdbc.standard.StandardXADataSource" destroy-method="shutdown"&gt;  <br />                 &lt;property name="transactionManager" ref="jotm"/&gt;  <br />                 &lt;property name="driverName" value="oracle.jdbc.driver.OracleDriver"/&gt;  <br />                 &lt;property name="url" value="jdbc:oracle:thin:@10.2.226.24:1521:voucher"/&gt;  <br />             &lt;/bean&gt;  <br />         &lt;/property&gt;  <br />         &lt;property name="user" value="boss"/&gt;  <br />         &lt;property name="password" value="boss"/&gt;  <br />     &lt;/bean&gt;  <br /><br />    &lt;tx:annotation-driven transaction-manager="txManager" proxy-target-class="true" /&gt; <br />           <br />&lt;!-- 第一个数据库的sqlMapClient --&gt; <br />&lt;bean id="sqlMapClient1" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean"&gt; <br />&lt;property name="configLocation"&gt; <br />&lt;!-- 包含第一个数据库表的map --&gt; <br />&lt;value&gt;classpath:SqlMapConfig_ora1.xml&lt;/value&gt; <br />&lt;/property&gt; <br />&lt;property name="dataSource" ref="dataSourceA" /&gt; <br />&lt;/bean&gt; <br />&lt;!-- 第二个数据库的sqlMapClient --&gt; <br />&lt;bean id="sqlMapClient2" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean"&gt; <br />&lt;property name="configLocation"&gt; <br />&lt;!-- 包含第一个数据库表的map --&gt; <br />&lt;value&gt;classpath:SqlMapConfig_ora2.xml&lt;/value&gt; <br />&lt;/property&gt; <br />&lt;property name="dataSource" ref="dataSourceB" /&gt; <br />&lt;/bean&gt; <br /><br /><br />&lt;bean id="product1Dao" class="com.crm.code.dao.impl.Product1DaoImpl"&gt; <br />&lt;property name="sqlMapClient"&gt; <br />&lt;ref bean="sqlMapClient1"/&gt; <br />&lt;/property&gt; <br />&lt;/bean&gt; <br />&lt;bean id="product2Dao" class="com.crm.code.dao.impl.Product2DaoImpl"&gt; <br />&lt;property name="sqlMapClient"&gt; <br />&lt;ref bean="sqlMapClient2"/&gt; <br />&lt;/property&gt; <br />&lt;/bean&gt; <br />&lt;bean id="product12Service" class="com.crm.code.service.impl.Product12ServiceImpl"&gt; <br />&lt;property name="product1Dao"&gt; <br />&lt;ref bean="product1Dao" /&gt; <br />&lt;/property&gt; <br />&lt;property name="product2Dao"&gt; <br />&lt;ref bean="product2Dao" /&gt; <br />&lt;/property&gt; <br />&lt;/bean&gt; <br />&lt;/beans&gt; <br /><img src ="http://www.blogjava.net/kyleYang/aggbug/305314.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/kyleYang/" target="_blank">飞熊</a> 2009-12-09 17:29 <a href="http://www.blogjava.net/kyleYang/articles/305314.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Spring中集成JOTM 配置JTA事务</title><link>http://www.blogjava.net/kyleYang/articles/305298.html</link><dc:creator>飞熊</dc:creator><author>飞熊</author><pubDate>Wed, 09 Dec 2009 08:41:00 GMT</pubDate><guid>http://www.blogjava.net/kyleYang/articles/305298.html</guid><wfw:comment>http://www.blogjava.net/kyleYang/comments/305298.html</wfw:comment><comments>http://www.blogjava.net/kyleYang/articles/305298.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/kyleYang/comments/commentRss/305298.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/kyleYang/services/trackbacks/305298.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 假如业务中要用到多个数据库，我们希望在业务方法中，当对某一个数据库的数据表进行操作的事务失败并回退（						rollback						），另外某一个数据库的数据表的操作事务也要回退，但应用一般的事务管理达不到这样的事务管理效果，这就需要实现						 JTA 						事务管理了。																																				...&nbsp;&nbsp;<a href='http://www.blogjava.net/kyleYang/articles/305298.html'>阅读全文</a><img src ="http://www.blogjava.net/kyleYang/aggbug/305298.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/kyleYang/" target="_blank">飞熊</a> 2009-12-09 16:41 <a href="http://www.blogjava.net/kyleYang/articles/305298.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Spring JTA应用之JOTM配置 </title><link>http://www.blogjava.net/kyleYang/articles/305293.html</link><dc:creator>飞熊</dc:creator><author>飞熊</author><pubDate>Wed, 09 Dec 2009 08:34:00 GMT</pubDate><guid>http://www.blogjava.net/kyleYang/articles/305293.html</guid><wfw:comment>http://www.blogjava.net/kyleYang/comments/305293.html</wfw:comment><comments>http://www.blogjava.net/kyleYang/articles/305293.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/kyleYang/comments/commentRss/305293.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/kyleYang/services/trackbacks/305293.html</trackback:ping><description><![CDATA[原文地址：http://tom-duan.javaeye.com/blog/147594<br /><br />JOTM(Java Open Transaction Manager)是ObjectWeb的一个开源JTA实现，本身也是开源应用程序服务器JOnAS(Java Open Application Server)的一部分，为其提供JTA分布式事务的功能。Spring对JOTM提供了较好的支持，提供了一个org.springframework.transaction.jta.JotmFactoryBean的支持类，在Spring2.0中也包含了JOTM相关的一些library。 <br /><br />jotm的下载地址为http://jotm.objectweb.org,最新版本为2.0.10. <br /><br />下载完成后解压缩，然后打开jotm下面conf文件夹，拷贝carol.properties文件到classpath中，并修改这个文件如下 <br />carol.properties <br /><div class="dp-highlighter"><div class="bar"><div class="tools">Java代码 <a title="复制代码" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;" href="http://tom-duan.javaeye.com/blog/147594#"></a></div></div><ol class="dp-j"><li><span><span># </span><span class="keyword">do</span><span> not use CAROL JNDI wrapper      </span></span></li><li><span>carol.start.jndi=</span><span class="keyword">false</span><span>      </span></li><li><span>      </span></li><li><span># </span><span class="keyword">do</span><span> not start a name server      </span></li><li><span>carol.start.ns=</span><span class="keyword">false</span><span>      </span></li><li><span>      </span></li><li><span># Naming Factory   </span></li><li><span>carol.jndi.java.naming.factory.url.pkgs=org.apache.naming  </span></li></ol></div><pre class="java" style="DISPLAY: none" name="code"># do not use CAROL JNDI wrapper
carol.start.jndi=false
# do not start a name server
carol.start.ns=false
# Naming Factory
carol.jndi.java.naming.factory.url.pkgs=org.apache.naming
</pre><br />上面配置文件的目的是不使用JNDI的方式来加载JOTM的配置，当然也可以根据需要选择其它的一些配置，例如JTOM所提供的默认配置。 <br /><br />然后开始在Spring上下文中配置JOTM，在classpath中建立一个ApplicationContext-jotm.xml，配置如下 <br /><br />ApplicationContext-jotm.xml <br /><div class="dp-highlighter"><div class="bar"><div class="tools">Java代码 <a title="复制代码" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;" href="http://tom-duan.javaeye.com/blog/147594#"></a></div></div><ol class="dp-j"><li><span><span>&lt;?xml version=</span><span class="string">"1.0"</span><span> encoding=</span><span class="string">"UTF-8"</span><span>?&gt;   </span></span></li><li><span>&lt;beans xmlns=</span><span class="string">"http://www.springframework.org/schema/beans"</span><span>  </span></li><li><span>    xmlns:xsi=</span><span class="string">"http://www.w3.org/2001/XMLSchema-instance"</span><span>  </span></li><li><span>    xsi:schemaLocation=</span><span class="string">"http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"</span><span>&gt;   </span></li><li><span>  </span></li><li><span>    &lt;bean id=</span><span class="string">"jotm"</span><span> </span><span class="keyword">class</span><span>=</span><span class="string">"org.springframework.transaction.jta.JotmFactoryBean"</span><span>/&gt;   </span></li><li><span>       </span></li><li><span>    &lt;bean id=</span><span class="string">"txManager"</span><span> </span><span class="keyword">class</span><span>=</span><span class="string">"org.springframework.transaction.jta.JtaTransactionManager"</span><span>&gt;   </span></li><li><span>        &lt;property name=</span><span class="string">"userTransaction"</span><span> ref=</span><span class="string">"jotm"</span><span> /&gt;   </span></li><li><span>    &lt;/bean&gt;   </span></li><li><span>  </span></li><li><span>    &lt;bean id=</span><span class="string">"ds1"</span><span> </span><span class="keyword">class</span><span>=</span><span class="string">"org.enhydra.jdbc.pool.StandardXAPoolDataSource"</span><span> destroy-method=</span><span class="string">"shutdown"</span><span>&gt;   </span></li><li><span>        &lt;property name=</span><span class="string">"dataSource"</span><span>&gt;   </span></li><li><span>            &lt;bean </span><span class="keyword">class</span><span>=</span><span class="string">"org.enhydra.jdbc.standard.StandardXADataSource"</span><span> destroy-method=</span><span class="string">"shutdown"</span><span>&gt;   </span></li><li><span>                &lt;property name=</span><span class="string">"transactionManager"</span><span> ref=</span><span class="string">"jotm"</span><span> /&gt;   </span></li><li><span>                &lt;property name=</span><span class="string">"driverName"</span><span> value=</span><span class="string">"com.mysql.jdbc.Driver"</span><span> /&gt;   </span></li><li><span>                &lt;property name=</span><span class="string">"url"</span><span> value=</span><span class="string">"jdbc:MySQL://localhost:3306/test"</span><span> /&gt;   </span></li><li><span>            &lt;/bean&gt;   </span></li><li><span>        &lt;/property&gt;   </span></li><li><span>        &lt;property name=</span><span class="string">"user"</span><span> value=</span><span class="string">"root"</span><span> /&gt;   </span></li><li><span>        &lt;property name=</span><span class="string">"password"</span><span> value=</span><span class="string">"admin"</span><span> /&gt;   </span></li><li><span>    &lt;/bean&gt;   </span></li><li><span>       </span></li><li><span>    &lt;bean id=</span><span class="string">"ds2"</span><span> </span><span class="keyword">class</span><span>=</span><span class="string">"org.enhydra.jdbc.pool.StandardXAPoolDataSource"</span><span> destroy-method=</span><span class="string">"shutdown"</span><span>&gt;   </span></li><li><span>        &lt;property name=</span><span class="string">"dataSource"</span><span>&gt;   </span></li><li><span>            &lt;bean </span><span class="keyword">class</span><span>=</span><span class="string">"org.enhydra.jdbc.standard.StandardXADataSource"</span><span> destroy-method=</span><span class="string">"shutdown"</span><span>&gt;   </span></li><li><span>                &lt;property name=</span><span class="string">"transactionManager"</span><span> ref=</span><span class="string">"jotm"</span><span> /&gt;   </span></li><li><span>                &lt;property name=</span><span class="string">"driverName"</span><span> value=</span><span class="string">"com.mysql.jdbc.Driver"</span><span> /&gt;   </span></li><li><span>                &lt;property name=</span><span class="string">"url"</span><span> value=</span><span class="string">"jdbc:MySQL://localhost:3306/test2"</span><span> /&gt;   </span></li><li><span>            &lt;/bean&gt;   </span></li><li><span>        &lt;/property&gt;   </span></li><li><span>        &lt;property name=</span><span class="string">"user"</span><span> value=</span><span class="string">"root"</span><span> /&gt;   </span></li><li><span>        &lt;property name=</span><span class="string">"password"</span><span> value=</span><span class="string">"admin"</span><span> /&gt;   </span></li><li><span>    &lt;/bean&gt;   </span></li><li><span>  </span></li><li><span>    &lt;bean id=</span><span class="string">"template1"</span><span> </span><span class="keyword">class</span><span>=</span><span class="string">"org.springframework.jdbc.core.JdbcTemplate"</span><span>&gt;   </span></li><li><span>        &lt;property name=</span><span class="string">"dataSource"</span><span> ref=</span><span class="string">"ds1"</span><span> /&gt;   </span></li><li><span>    &lt;/bean&gt;   </span></li><li><span>       </span></li><li><span>    &lt;bean id=</span><span class="string">"template2"</span><span> </span><span class="keyword">class</span><span>=</span><span class="string">"org.springframework.jdbc.core.JdbcTemplate"</span><span>&gt;   </span></li><li><span>        &lt;property name=</span><span class="string">"dataSource"</span><span> ref=</span><span class="string">"ds2"</span><span> /&gt;   </span></li><li><span>    &lt;/bean&gt;   </span></li><li><span>       </span></li><li><span>    &lt;bean id=</span><span class="string">"dao1"</span><span> </span><span class="keyword">class</span><span>=</span><span class="string">"com.xa.dao.UserDao1"</span><span>&gt;   </span></li><li><span>        &lt;property name=</span><span class="string">"jdbcTemplate"</span><span>&gt;   </span></li><li><span>            &lt;ref bean=</span><span class="string">"template1"</span><span>&gt;&lt;/ref&gt;   </span></li><li><span>        &lt;/property&gt;   </span></li><li><span>    &lt;/bean&gt;   </span></li><li><span>       </span></li><li><span>    &lt;bean id=</span><span class="string">"dao2"</span><span> </span><span class="keyword">class</span><span>=</span><span class="string">"com.xa.dao.UserDao2"</span><span>&gt;   </span></li><li><span>        &lt;property name=</span><span class="string">"jdbcTemplate"</span><span>&gt;   </span></li><li><span>            &lt;ref bean=</span><span class="string">"template2"</span><span>&gt;&lt;/ref&gt;   </span></li><li><span>        &lt;/property&gt;   </span></li><li><span>    &lt;/bean&gt;   </span></li><li><span>       </span></li><li><span>    &lt;bean id=</span><span class="string">"userServiceTarget"</span><span> </span><span class="keyword">class</span><span>=</span><span class="string">"com.xa.service.UserServiceImpl"</span><span>&gt;   </span></li><li><span>        &lt;property name=</span><span class="string">"dao1"</span><span> ref=</span><span class="string">"dao1"</span><span>/&gt;   </span></li><li><span>        &lt;property name=</span><span class="string">"dao2"</span><span> ref=</span><span class="string">"dao2"</span><span>/&gt;   </span></li><li><span>    &lt;/bean&gt;   </span></li><li><span>  </span></li><li><span>  </span></li><li><span>    &lt;bean id=</span><span class="string">"userTest"</span><span> </span><span class="keyword">class</span><span>=</span><span class="string">"org.springframework.transaction.interceptor.TransactionProxyFactoryBean"</span><span>&gt;       </span></li><li><span>        &lt;property name=</span><span class="string">"transactionManager"</span><span>&gt;   </span></li><li><span>            &lt;ref bean=</span><span class="string">"txManager"</span><span>/&gt;   </span></li><li><span>        &lt;/property&gt;       </span></li><li><span>        &lt;property name=</span><span class="string">"target"</span><span>&gt;   </span></li><li><span>            &lt;ref bean=</span><span class="string">"userServiceTarget"</span><span>/&gt;   </span></li><li><span>        &lt;/property&gt;   </span></li><li><span>        &lt;property name=</span><span class="string">"transactionAttributes"</span><span>&gt;           </span></li><li><span>            &lt;props&gt;   </span></li><li><span>                &lt;prop key=</span><span class="string">"insert*"</span><span>&gt;PROPAGATION_REQUIRED,-Exception&lt;/prop&gt;               </span></li><li><span>            &lt;/props&gt;   </span></li><li><span>        &lt;/property&gt;   </span></li><li><span>    &lt;/bean&gt;   </span></li><li><span>&lt;/beans&gt;  </span></li></ol></div><pre class="java" style="DISPLAY: none" name="code">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"&gt;
&lt;bean id="jotm" class="org.springframework.transaction.jta.JotmFactoryBean"/&gt;
&lt;bean id="txManager" class="org.springframework.transaction.jta.JtaTransactionManager"&gt;
&lt;property name="userTransaction" ref="jotm" /&gt;
&lt;/bean&gt;
&lt;bean id="ds1" class="org.enhydra.jdbc.pool.StandardXAPoolDataSource" destroy-method="shutdown"&gt;
&lt;property name="dataSource"&gt;
&lt;bean class="org.enhydra.jdbc.standard.StandardXADataSource" destroy-method="shutdown"&gt;
&lt;property name="transactionManager" ref="jotm" /&gt;
&lt;property name="driverName" value="com.mysql.jdbc.Driver" /&gt;
&lt;property name="url" value="jdbc:MySQL://localhost:3306/test" /&gt;
&lt;/bean&gt;
&lt;/property&gt;
&lt;property name="user" value="root" /&gt;
&lt;property name="password" value="admin" /&gt;
&lt;/bean&gt;
&lt;bean id="ds2" class="org.enhydra.jdbc.pool.StandardXAPoolDataSource" destroy-method="shutdown"&gt;
&lt;property name="dataSource"&gt;
&lt;bean class="org.enhydra.jdbc.standard.StandardXADataSource" destroy-method="shutdown"&gt;
&lt;property name="transactionManager" ref="jotm" /&gt;
&lt;property name="driverName" value="com.mysql.jdbc.Driver" /&gt;
&lt;property name="url" value="jdbc:MySQL://localhost:3306/test2" /&gt;
&lt;/bean&gt;
&lt;/property&gt;
&lt;property name="user" value="root" /&gt;
&lt;property name="password" value="admin" /&gt;
&lt;/bean&gt;
&lt;bean id="template1" class="org.springframework.jdbc.core.JdbcTemplate"&gt;
&lt;property name="dataSource" ref="ds1" /&gt;
&lt;/bean&gt;
&lt;bean id="template2" class="org.springframework.jdbc.core.JdbcTemplate"&gt;
&lt;property name="dataSource" ref="ds2" /&gt;
&lt;/bean&gt;
&lt;bean id="dao1" class="com.xa.dao.UserDao1"&gt;
&lt;property name="jdbcTemplate"&gt;
&lt;ref bean="template1"&gt;&lt;/ref&gt;
&lt;/property&gt;
&lt;/bean&gt;
&lt;bean id="dao2" class="com.xa.dao.UserDao2"&gt;
&lt;property name="jdbcTemplate"&gt;
&lt;ref bean="template2"&gt;&lt;/ref&gt;
&lt;/property&gt;
&lt;/bean&gt;
&lt;bean id="userServiceTarget" class="com.xa.service.UserServiceImpl"&gt;
&lt;property name="dao1" ref="dao1"/&gt;
&lt;property name="dao2" ref="dao2"/&gt;
&lt;/bean&gt;
&lt;bean id="userTest" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"&gt;
&lt;property name="transactionManager"&gt;
&lt;ref bean="txManager"/&gt;
&lt;/property&gt;
&lt;property name="target"&gt;
&lt;ref bean="userServiceTarget"/&gt;
&lt;/property&gt;
&lt;property name="transactionAttributes"&gt;
&lt;props&gt;
&lt;prop key="insert*"&gt;PROPAGATION_REQUIRED,-Exception&lt;/prop&gt;
&lt;/props&gt;
&lt;/property&gt;
&lt;/bean&gt;
&lt;/beans&gt;
</pre><br />上面是一个完整的Spring上下文配置，可以看第一个bean “jotm”，实际上引用了Spring内部所提供的对JOTM支持的工厂类，参考下面的配置代码段 <br /><div class="dp-highlighter"><div class="bar"><div class="tools">Java代码 <a title="复制代码" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;" href="http://tom-duan.javaeye.com/blog/147594#"></a></div></div><ol class="dp-j"><li><span><span>&lt;bean id=</span><span class="string">"jotm"</span><span> </span><span class="keyword">class</span><span>=</span><span class="string">"org.springframework.transaction.jta.JotmFactoryBean"</span><span>/&gt;  </span></span></li></ol></div><pre class="java" style="DISPLAY: none" name="code">&lt;bean id="jotm" class="org.springframework.transaction.jta.JotmFactoryBean"/&gt;
</pre><br /><br />随后，配置了JTA事务管理器，并且在管理器中使用上面所配置的jotm，如下面的代码 <br /><div class="dp-highlighter"><div class="bar"><div class="tools">Java代码 <a title="复制代码" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;" href="http://tom-duan.javaeye.com/blog/147594#"></a></div></div><ol class="dp-j"><li><span><span>&lt;bean id=</span><span class="string">"txManager"</span><span> </span><span class="keyword">class</span><span>=</span><span class="string">"org.springframework.transaction.jta.JtaTransactionManager"</span><span>&gt;   </span></span></li><li><span>    &lt;property name=</span><span class="string">"userTransaction"</span><span> ref=</span><span class="string">"jotm"</span><span> /&gt;   </span></li><li><span>&lt;/bean&gt;  </span></li></ol></div><pre class="java" style="DISPLAY: none" name="code">&lt;bean id="txManager" class="org.springframework.transaction.jta.JtaTransactionManager"&gt;
&lt;property name="userTransaction" ref="jotm" /&gt;
&lt;/bean&gt;
</pre><br /><br />再接下来就是配置多个数据源了，使用jotm提供的org.enhydra.jdbc.pool.StandardXAPoolDataSource类，根据类名可以明确地看出它是用以配置多个数据源的啦,配置的代码如下 <br /><div class="dp-highlighter"><div class="bar"><div class="tools">Java代码 <a title="复制代码" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;" href="http://tom-duan.javaeye.com/blog/147594#"></a></div></div><ol class="dp-j"><li><span><span>&lt;bean id=</span><span class="string">"ds1"</span><span> </span><span class="keyword">class</span><span>=</span><span class="string">"org.enhydra.jdbc.pool.StandardXAPoolDataSource"</span><span> destroy-method=</span><span class="string">"shutdown"</span><span>&gt;   </span></span></li><li><span>        &lt;property name=</span><span class="string">"dataSource"</span><span>&gt;   </span></li><li><span>            &lt;bean </span><span class="keyword">class</span><span>=</span><span class="string">"org.enhydra.jdbc.standard.StandardXADataSource"</span><span> destroy-method=</span><span class="string">"shutdown"</span><span>&gt;   </span></li><li><span>                &lt;property name=</span><span class="string">"transactionManager"</span><span> ref=</span><span class="string">"jotm"</span><span> /&gt;   </span></li><li><span>                &lt;property name=</span><span class="string">"driverName"</span><span> value=</span><span class="string">"com.mysql.jdbc.Driver"</span><span> /&gt;   </span></li><li><span>                &lt;property name=</span><span class="string">"url"</span><span> value=</span><span class="string">"jdbc:MySQL://localhost:3306/test"</span><span> /&gt;   </span></li><li><span>            &lt;/bean&gt;   </span></li><li><span>        &lt;/property&gt;   </span></li><li><span>        &lt;property name=</span><span class="string">"user"</span><span> value=</span><span class="string">"root"</span><span> /&gt;   </span></li><li><span>        &lt;property name=</span><span class="string">"password"</span><span> value=</span><span class="string">"admin"</span><span> /&gt;   </span></li><li><span>    &lt;/bean&gt;   </span></li><li><span>       </span></li><li><span>    &lt;bean id=</span><span class="string">"ds2"</span><span> </span><span class="keyword">class</span><span>=</span><span class="string">"org.enhydra.jdbc.pool.StandardXAPoolDataSource"</span><span> destroy-method=</span><span class="string">"shutdown"</span><span>&gt;   </span></li><li><span>        &lt;property name=</span><span class="string">"dataSource"</span><span>&gt;   </span></li><li><span>            &lt;bean </span><span class="keyword">class</span><span>=</span><span class="string">"org.enhydra.jdbc.standard.StandardXADataSource"</span><span> destroy-method=</span><span class="string">"shutdown"</span><span>&gt;   </span></li><li><span>                &lt;property name=</span><span class="string">"transactionManager"</span><span> ref=</span><span class="string">"jotm"</span><span> /&gt;   </span></li><li><span>                &lt;property name=</span><span class="string">"driverName"</span><span> value=</span><span class="string">"com.mysql.jdbc.Driver"</span><span> /&gt;   </span></li><li><span>                &lt;property name=</span><span class="string">"url"</span><span> value=</span><span class="string">"jdbc:MySQL://localhost:3306/test2"</span><span> /&gt;   </span></li><li><span>            &lt;/bean&gt;   </span></li><li><span>        &lt;/property&gt;   </span></li><li><span>        &lt;property name=</span><span class="string">"user"</span><span> value=</span><span class="string">"root"</span><span> /&gt;   </span></li><li><span>        &lt;property name=</span><span class="string">"password"</span><span> value=</span><span class="string">"admin"</span><span> /&gt;   </span></li><li><span>    &lt;/bean&gt;  </span></li></ol></div><pre class="java" style="DISPLAY: none" name="code">&lt;bean id="ds1" class="org.enhydra.jdbc.pool.StandardXAPoolDataSource" destroy-method="shutdown"&gt;
&lt;property name="dataSource"&gt;
&lt;bean class="org.enhydra.jdbc.standard.StandardXADataSource" destroy-method="shutdown"&gt;
&lt;property name="transactionManager" ref="jotm" /&gt;
&lt;property name="driverName" value="com.mysql.jdbc.Driver" /&gt;
&lt;property name="url" value="jdbc:MySQL://localhost:3306/test" /&gt;
&lt;/bean&gt;
&lt;/property&gt;
&lt;property name="user" value="root" /&gt;
&lt;property name="password" value="admin" /&gt;
&lt;/bean&gt;
&lt;bean id="ds2" class="org.enhydra.jdbc.pool.StandardXAPoolDataSource" destroy-method="shutdown"&gt;
&lt;property name="dataSource"&gt;
&lt;bean class="org.enhydra.jdbc.standard.StandardXADataSource" destroy-method="shutdown"&gt;
&lt;property name="transactionManager" ref="jotm" /&gt;
&lt;property name="driverName" value="com.mysql.jdbc.Driver" /&gt;
&lt;property name="url" value="jdbc:MySQL://localhost:3306/test2" /&gt;
&lt;/bean&gt;
&lt;/property&gt;
&lt;property name="user" value="root" /&gt;
&lt;property name="password" value="admin" /&gt;
&lt;/bean&gt;
</pre><br />这里配置的两个数据源都连接到本地的mysql，实际上可以连接到不同的db server和不同类型的数据库，已经经过测试，这里为了方便，在本地建立了两个不同的数据库(test,test2)做测试。 <br /><br />随后的配置基本上和普通的Spring上下文配置相同了，根据不同的数据源配置两个jdbcTemplate，两个dao分别引用不同的jdbcTemplate, 将两个dao注入到UserService中, 最后将service纳入事务管理,并在事务代理配置中配置回滚规则,意思为如遇异常，则强制回滚内容。配置如下所示 <br /><div class="dp-highlighter"><div class="bar"><div class="tools">Java代码 <a title="复制代码" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;" href="http://tom-duan.javaeye.com/blog/147594#"></a></div></div><ol class="dp-j"><li><span><span>&lt;property name=</span><span class="string">"transactionAttributes"</span><span>&gt;           </span></span></li><li><span>    &lt;props&gt;   </span></li><li><span>        &lt;prop key=</span><span class="string">"insert*"</span><span>&gt;PROPAGATION_REQUIRED,-Exception&lt;/prop&gt;               </span></li><li><span>    &lt;/props&gt;   </span></li><li><span>&lt;/property&gt;  </span></li></ol></div><pre class="java" style="DISPLAY: none" name="code">&lt;property name="transactionAttributes"&gt;
&lt;props&gt;
&lt;prop key="insert*"&gt;PROPAGATION_REQUIRED,-Exception&lt;/prop&gt;
&lt;/props&gt;
&lt;/property&gt;
</pre><br /><br />这样，一个使用JOTM JTA事务的简单应用算大致成型了，最后，写一个JUnit，来测试一下结果 <br />TestXa.java <br /><div class="dp-highlighter"><div class="bar"><div class="tools">Java代码 <a title="复制代码" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;" href="http://tom-duan.javaeye.com/blog/147594#"></a></div></div><ol class="dp-j"><li><span><span class="keyword">package</span><span> com.xa;   </span></span></li><li><span>  </span></li><li><span class="keyword">import</span><span> org.springframework.context.ApplicationContext;   </span></li><li><span class="keyword">import</span><span> org.springframework.test.AbstractDependencyInjectionSpringContextTests;   </span></li><li><span>  </span></li><li><span class="keyword">import</span><span> com.xa.service.UserService;   </span></li><li><span>  </span></li><li><span class="keyword">public</span><span> </span><span class="keyword">class</span><span> TestXa </span><span class="keyword">extends</span><span> AbstractDependencyInjectionSpringContextTests   </span></li><li><span>{   </span></li><li><span>    </span><span class="keyword">protected</span><span> String[] getConfigLocations() {   </span></li><li><span>        </span><span class="keyword">return</span><span> </span><span class="keyword">new</span><span> String[] { </span><span class="string">"classpath:ApplicationContext-jotm.xml"</span><span> };   </span></li><li><span>    }   </span></li><li><span>  </span></li><li><span>    </span><span class="keyword">public</span><span> </span><span class="keyword">void</span><span> testInsertBothDatabase() {   </span></li><li><span>        ApplicationContext ctx = </span><span class="keyword">this</span><span>.getApplicationContext();   </span></li><li><span>        UserService ut = (UserService)ctx.getBean(</span><span class="string">"userTest"</span><span>);   </span></li><li><span>        </span><span class="keyword">try</span><span> {   </span></li><li><span>            ut.insertBothDatabase(</span><span class="string">"1"</span><span>, </span><span class="keyword">null</span><span>);   </span></li><li><span>        }   </span></li><li><span>        </span><span class="keyword">catch</span><span> (Exception e) {   </span></li><li><span>            e.printStackTrace();   </span></li><li><span>        }   </span></li><li><span>    }   </span></li><li><span>}  </span></li></ol></div><pre class="java" style="DISPLAY: none" name="code">package com.xa;
import org.springframework.context.ApplicationContext;
import org.springframework.test.AbstractDependencyInjectionSpringContextTests;
import com.xa.service.UserService;
public class TestXa extends AbstractDependencyInjectionSpringContextTests
{
protected String[] getConfigLocations() {
return new String[] { "classpath:ApplicationContext-jotm.xml" };
}
public void testInsertBothDatabase() {
ApplicationContext ctx = this.getApplicationContext();
UserService ut = (UserService)ctx.getBean("userTest");
try {
ut.insertBothDatabase("1", null);
}
catch (Exception e) {
e.printStackTrace();
}
}
}
</pre><br />在test中，调用了UserService的insertBothDatabase方法，有两个参数，userId和UserName，另外在方法的实现中调用了两个使用不同数据源dao，分别向两个不同的数据库插入输入，而test2数据库的xa_test表中，name字段是不允许为空的，因此，在插入test2数据库时会失败. <br /><br />运行这个test，然后察看数据库结果：），test和test2数据库中都没有插入成功，看serviceImpl中的代码可以知道，逻辑上dao1会先于dao2执行，但是由于JTA事务，在dao2插入数据出现异常时整个事务被回滚，由于事务被配置在service层，dao1和dao2都被纳入一个事务进行管理，呵呵。修改一下方法的参数，修改为 <br /><div class="dp-highlighter"><div class="bar"><div class="tools">Java代码 <a title="复制代码" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;" href="http://tom-duan.javaeye.com/blog/147594#"></a></div></div><ol class="dp-j"><li><span><span>ut.insertBothDatabase(</span><span class="string">"1"</span><span>, </span><span class="string">"name1"</span><span>);  </span></span></li></ol></div><pre class="java" style="DISPLAY: none" name="code">ut.insertBothDatabase("1", "name1");
</pre><br /><br />然后再试试test看数据库结果，如何？ <br /><img src ="http://www.blogjava.net/kyleYang/aggbug/305293.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/kyleYang/" target="_blank">飞熊</a> 2009-12-09 16:34 <a href="http://www.blogjava.net/kyleYang/articles/305293.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>