- 浏览: 218302 次
- 性别:
- 来自: 武汉
文章分类
- 全部博客 (110)
- java (111)
- c# winform tablelayoutpanel学习 合并行的布局及动态增加删除内部控件 (1)
- javascript常用正则 (1)
- 认识Java程序 (1)
- UniqTask for android (1)
- JAX-RS 从傻逼到牛叉 2:开发一个简单的服务 (1)
- Spring MVC 数据绑定的扩展 (1)
- 手机分辨率 (1)
- tomcat的favicon.ico的用法 (1)
- Cookie读写demo (1)
- hive相关操作文档收集 (1)
- 测试开发工程师的发展 (1)
- JSF入门十(自定义转换器) (1)
- 《你能行:微软精英的职场心里话》 (1)
- JNI程序如何检测C代码的内存泄漏 (1)
- 做了几天的调研工作 (1)
- 使用Microsoft Web Application Stress进行压力测试 (1)
- 在线共享音乐吧(Online Share Music Bar)解决方案 (1)
- 如何二次压缩RM和RMVB格式文件 (1)
- 突然想起了红色联盟 就去看了看 (1)
- 推荐两个关于DB2认证的站点 (1)
- 安装Microsoft .NET Framework SDK 快速入门、教程和示例 (1)
- 去掉C/C++程序代码中的注释 (1)
- 数据结构之kmp模式匹配 (1)
- JS跨域 (1)
- SP2-0734: 未知的命令开头 "exp test/t..." - 忽略了剩余的行 解决办法 (1)
- Android开发之fedora13下编译Android源码 (1)
- Android开发之Linkify (1)
- json学习之三:JSONArray的应用 (1)
- js 数组操作代码集锦 (1)
- jquery跨域调用json数据 (1)
- qtdemo浅析 (1)
最新评论
-
songshuang:
最近怎么都盗我的文
做个小调查,程序员们都是什么星座的?
jotm 包括 jotm-core.jar、ow2-connector-1.5-spec.jar、jotm-client.jar、xapool.jar。
jotm-core.jar、ow2-connector-1.5-spec.jar、jotm-client.jar 主要是提供对transaction 的管理。
xapool.jar提供 xa datesource 以及 connection pool 。
其实个人觉得 学习jta 的切入点只有一个 ,为什么要使用 xa datesource ,而且要求是如此的强烈,以至于让我很想弄明白。
一般的解释就是:jta(java transaction api) 为 j2ee 平台提供了分布式事务服务。要用 jta 进行事务界定,应用程序要调用 javax.transaction.usertransaction 接口中的方法。例如:
utx.begin();
// ...
datasource ds = obtainxadatasource();
connection conn = ds.getconnection();
pstmt = conn.preparestatement("update movies ...");
pstmt.setstring(1, "spinal tap");
pstmt.executeupdate();
// ...
utx.commit();
“用 jta 界定事务,那么就需要有一个实现 javax.sql.xadatasource 、 javax.sql.xaconnection 和 javax.sql.xaresource 接口的 jdbc 驱动程序。一个实现了这些接口的驱动程序将可以参与 jta 事务。一个 xadatasource 对象就是一个 xaconnection 对象的工厂。 xaconnection s 是参与 jta 事务的 jdbc 连接。”
要使用jta事务,必须使用xadatasource来产生数据库连接,产生的连接为一个xa连接。
jta方式的实现过程:
用xadatasource产生的xaconnection它扩展了一个getxaresource()方法,事务通过这个方法把它加入到事务容器中进行管理。
[---------------------来至baidu---------------------]
但我觉得还是不能理解,问题是还不能解释我原来提出的切入点[为什么要使用 xa datesource],能解释的只有一句话:用xadatasource产生的xaconnection它扩展了一个getxaresource()方法,事务通过这个方法把它加入到事务容器中进行管理,显然这不能让人满意!
所以我要解释的就是 jta 为什么只能使用xa datesource,要解释这一点,我们要先了解 普通的 jdbc transaction[hibernate transaction] 又是一个什么原理:在这里我结合 spring aop 讲解 jdbc transaction[hibernate transaction]
这是jdbc transaction[hibernate transaction] 使用 spring aop 的配置:
<!-- datasource 其实已经被c3p0 包装过了 -->
<bean id="datasource"
class="com.mchange.v2.c3p0.combopooleddatasource"
destroy-method="close" dependency-check="none">
<property name="driverclass">
<value>${datasource.driverclassname}</value>
</property>
<property name="jdbcurl">
<value>${datasource.url}</value>
</property>
<property name="user">
<value>${datasource.username}</value>
</property>
<property name="password">
<value>${datasource.password}</value>
</property>
<property name="acquireincrement">
<value>${c3p0.acquireincrement}</value>
</property>
<property name="initialpoolsize">
<value>${c3p0.initialpoolsize}</value>
</property>
<property name="minpoolsize">
<value>${c3p0.minpoolsize}</value>
</property>
<property name="maxpoolsize">
<value>${c3p0.maxpoolsize}</value>
</property>
<property name="maxidletime">
<value>${c3p0.maxidletime}</value>
</property>
<property name="idleconnectiontestperiod">
<value>${c3p0.idleconnectiontestperiod}</value>
</property>
<property name="maxstatements">
<value>${c3p0.maxstatements}</value>
</property>
<property name="numhelperthreads">
<value>${c3p0.numhelperthreads}</value>
</property>
</bean>
<bean id="sessionfactory"
class="org.springframework.orm.hibernate3.localsessionfactorybean">
<property name="datasource">
<ref local="datasource" />
</property>
<property name="mappingresources">
......内容太多 ,不在显示
</property>
</bean>
<!-- transactionmanager-->
<bean id="mytransactionmanager"
class="org.springframework.orm.hibernate3.hibernatetransactionmanager">
<property name="sessionfactory">
<ref local="sessionfactory" />
</property>
</bean>
<!-- 配置事务处理 -->
<bean id="txproxytemplate" abstract="true"
class="org.springframework.transaction.interceptor.transactionproxyfactorybean">
<property name="transactionmanager">
<ref bean="mytransactionmanager" />
</property>
<property name="transactionattributes">
....拦截 dao 或 service 的配置
</property>
</bean>
我们将sessionfactory 传给了transactionmanager、然后transactionmanager 传给transactionproxyfactorybean
然后我们一般还会配置 dao ,例如 [把sessionfactory 传给 dao]
<bean id="permissiondao"
class="sezelee.sample.bbsse.dao.hibernate.permissionhibernatedao">
<property name="sessionfactory">
<ref local="sessionfactory" />
</property>
</bean>
好,现在说 permissiondao 的事务拦截的调用过程[关注的是transaction 的流向]:
假设代码 调用 permissiondao 的某个方法之前事务拦截,我们就从transactionproxyfactorybean 中mytransactionmanager中获取connection ,然后获取 transaction 事务。
说明 :mytransactionmanager中已经有 sessionfactory ,我们就是从sessionfactory中获取connection ,然后由connection 获取transaction ,sessionfactory 获取connection 的时候,就将connection 放入 threadlocal[和线程绑定]。
下面正式执行我们的业务逻辑:比如permissiondao 中的 save(); save()中必然要使用到数据库的connection 。我们从哪里获取 呢, permissiondao中不是有传进sessionfactory 吗?和mytransactionmanager 从sessionfactory获取connention 的道理一样, save()中用到的 connection也从 sessionfactory 获取,那么 此时从sessionfactory 获取的connection就是之前放入threadlocal的connection ,save() 执行完毕。
在提交[commit]或回滚[rollback] 的时候我们获取的还是之前放入threadlocal的connection ,为此整个事务的开始到结束 我们使用的都是 同一个 connection。
这就是 普通 jdbc transaction 结合 spring aop
那 jta 又是怎么个情况呢?
我们直接从 jta 使用spring aop 的配置入手。
<!-- jta 事务-->
<bean id="jotm" class="org.springframework.transaction.jta.jotmfactorybean" />
<bean id="jtatransactionmanager" class="org.springframework.transaction.jta.jtatransactionmanager">
<property name="usertransaction" ref="jotm" />
</bean>
<!-- xadatasource-->
<bean id="innerdatasource" class="org.enhydra.jdbc.standard.standardxadatasource" destroy-method="shutdown">
<property name="transactionmanager" ref="jotm"/>
<property name="drivername">
<value>${datasource.driverclassname}</value>
</property>
<property name="url">
<value>${datasource.url}</value>
</property>
<property name="user">
<value>${datasource.username}</value>
</property>
<property name="password">
<value>${datasource.password}</value>
</property>
<property name="maxcon" value="50" />
<property name="mincon" value="5" />
<property name="preparedstmtcachesize" value="5"/>
</bean>
<!-- 对 innerdatasource 进行pool 包装-->
<bean id="datasource" class="org.enhydra.jdbc.pool.standardxapooldatasource" destroy-method="shutdown">
<property name="datasource" ref="innerdatasource"/>
<property name="user" value="root"/>
<property name="password" value=""/>
<property name="minsize" value="2"/>
<property name="maxsize" value="50"/>
<property name="deadlockmaxwait" value="1000"/>
<property name="deadlockretrywait" value="600"/>
</bean>
<bean id="sessionfactory"
class="org.springframework.orm.hibernate3.localsessionfactorybean">
<property name="datasource">
<ref local="datasource" />
</property>
<property name="mappingresources">
......
</property>
</bean>
<!-- 配置事务处理 -->
<bean id="txproxytemplate" abstract="true"
class="org.springframework.transaction.interceptor.transactionproxyfactorybean">
<property name="transactionmanager">
<ref bean="jtatransactionmanager" />
</property>
<property name="transactionattributes">
.....
</property>
</bean>
<!-- 配置事物处理 -->
<!-- about permission dao -->
<bean id="permissiondao"
class="sezelee.sample.bbsse.dao.hibernate.permissionhibernatedao">
<property name="sessionfactory">
<ref local="sessionfactory" />
</property>
</bean>
那么这段代码和 上面的jdbc transaction 有什么不同呢 ?
此时 transactionmanager[jtatransactionmanager] 传入的不在是sessionfactory ,而是 jtom。
jtom 到底是什么 呢 ,不用着急我们 往下看, 仔细看 innerdatasource 有什么不同,多了一个jotm。
这是为什么呢?
我们还是从 permissiondao 的事务拦截的调用过程 开始 [关注的是transaction 的流向]:
假设代码 调用 permissiondao 的某个方法之前事务拦截,
比如说 update() 方法: 里面需要获取 两个 connection [来至不同的数据源]。
比如 第一个来至 datesource1 、 第二个来至 datesource2
还记得 innerdatasource 中 配置的jtom 吗?
通过 sessionfactory 我们获取 第一个 datesource1 的 connention 时 将connention 放入jtom。我们获取 第二个 datesource2 的 connention 时将connention 放入jtom
jtom 也同时传到了jtatransactionmanager ,update() 方法业务执行完毕。
在提交[commit]或回滚[rollback] 的时候 ,我们就从 jtatransactionmanager 中 的 jtom 获取datesource1 的 connention、datesource2 的 connention
然后加上这样的逻辑 ,只要其中有一个异常 ,就全部rollback。
try{ datesource1.connention.transaction.commit datesource2.connention.transaction.commit
}catch(exception e){
datesource1.connention.transaction.rollback
datesource2.connention.transaction.rollback
}
所以我们 进行数据库操作的 connention 都是放入jtom或从jtom获取[其实jtom 的connection 还是 绑定到 threadlocal] 。
我们 就简单的将 jtom 理解为 一个 map , 获取connection 时将 connection放入这个map。然后 我们 将map 传给transactionmanager ,当事务要提交/回滚的时候我们从transactionmanager 获取这个map
spring 给我们提供了这样一个transactionmanager [jtatransactionmanager]。
以上就是对[用xadatasource产生的xaconnection它扩展了一个getxaresource()方法,事务通过这个方法把它加入到事务容器中进行管理] 这句话的解释。
到此我们 回到 刚开始的切入点:为什么要使用 xa datesource。
xa datesource 提供了 在获取 connecntion时 将connecntion放入 jtom 的支持。
而 datesource 是没有提供这种 支持的。
好了 !全文结束 ,以上是我对 jta 的个人理解 ,有不对的地方,请大家指点!
发表评论
-
qtdemo浅析
2012-02-07 16:14 1585[size=x-small;]? ? <span ... -
jquery跨域调用json数据
2012-02-03 11:39 1435? <script type="te ... -
js 数组操作代码集锦
2012-02-03 10:59 1144[size=small;]这段时间做的一个项目,用到数 ... -
json学习之三:JSONArray的应用
2012-02-02 15:29 71524从json数组中得到 ... -
Android开发之Linkify
2012-01-31 13:33 2211<h1>Android开发之Linkify ... -
Android开发之fedora13下编译Android源码
2012-01-11 16:04 1153<h1>Android开发之fedora1 ... -
SP2-0734: 未知的命令开头 "exp test/t..." - 忽略了剩余的行 解决办法
2011-12-28 14:13 3870<span style="font-f ... -
JS跨域
2011-12-21 16:43 2638原帖地址:http://itgeeker.com/ma ... -
数据结构之kmp模式匹配
2011-12-21 10:04 1185KMP字符串模式匹配详解 KMP字符串模式匹配通俗点说 ... -
去掉C/C++程序代码中的注释
2011-12-20 16:49 3060程序员面试宝典上面的题目有很多是很经典的问题,可供我 ... -
安装Microsoft .NET Framework SDK 快速入门、教程和示例
2011-12-19 10:09 2054Microsoft .NET Framework SD ... -
推荐两个关于DB2认证的站点
2011-12-19 09:59 848关于DB2认证的在线中文教程<br>htt ... -
突然想起了红色联盟 就去看了看
2011-12-17 10:54 1181突然想起了红色联盟,于是就偷偷的爬上红盟站点,看了看红 ... -
如何二次压缩RM和RMVB格式文件
2011-12-16 17:12 1121对RM/RMVB格式文件进行二次压缩,可以用一个软件E ... -
在线共享音乐吧(Online Share Music Bar)解决方案
2011-12-14 19:54 998</span></font>& ... -
使用Microsoft Web Application Stress进行压力测试
2011-12-14 18:33 879<font size="2" ... -
做了几天的调研工作
2011-12-14 17:29 1017</span></span> ... -
JNI程序如何检测C代码的内存泄漏
2011-12-13 14:59 1449Java调用C的JNI程序很容易出现内存泄漏问题,因为 ... -
《你能行:微软精英的职场心里话》
2011-12-12 14:39 961<p class="MsoNorm ... -
JSF入门十(自定义转换器)
2011-12-09 11:00 975本文参考 http://www.javaworld.c ...
评论