心情小站
勤学、勤思
BlogJava
首页
新随笔
联系
聚合
管理
posts - 112, comments - 265, trackbacks - 0
ibatis DAO 事务探索
ibatis DAO 框架提供了事务管理模块。而这个事务管理可以应用到很多场合,包括JDBC、Hibernate、JTA、SQLMAP等。
下面以最简单的JDBC来分析一下其如何实现事务管理。
首先来看一段代码:
public
class
OrderService
{
private
DaoManager daoManager;
private
OrderDao orderDao;
public
OrderService()
{
daoManager
=
DaoConfig.getDaoManager();
orderDao
=
(OrderDao) daoManager.getDao(OrderDao.
class
);
}
public
void
method()
{
try
{
//
a separate transaction
orderDao.method1();
//
第一个事务
daoManager.startTransaction();
//
开始第二个事务
orderDao.method1();
orderDao.method2();
daoManager.commitTransaction();
//
提交第二个事务
}
finally
{
daoManager.endTransaction();
}
}
}
在method()方法里有着两个事务,如果在方法里不显式的调用daoManager.startTransaction(),则每个DAO的一次方法调用就是一个独立的事务。
ibatis DAO事务,有两个核心接口DaoTransactionManager和DaoTransaction
对应着不同的数据库持久层实现,两个接口分别对应着不同实现
查看ibatis 代码,可以发现这些manager实现事务,就是调用事务源的事务操作方法
JdbcDaoTransactionManager
public
void
commitTransaction(DaoTransaction trans)
{
((JdbcDaoTransaction) trans).commit();
}
JdbcDaoTransaction
public
JdbcDaoTransaction(DataSource dataSource)
{
try
{
connection
=
dataSource.getConnection();
if
(connection
==
null
)
{
throw
new
DaoException(
"
Could not start transaction. Cause: The DataSource returned a null connection.
"
);
}
if
(connection.getAutoCommit())
{
connection.setAutoCommit(
false
);
}
if
(connectionLog.isDebugEnabled())
{
connection
=
ConnectionLogProxy.newInstance(connection);
}
}
catch
(SQLException e)
{
throw
new
DaoException(
"
Error starting JDBC transaction. Cause:
"
+
e);
}
}
public
void
commit()
{
try
{
try
{
connection.commit();
}
finally
{
connection.close();
}
}
catch
(SQLException e)
{
throw
new
DaoException(
"
Error committing JDBC transaction. Cause:
"
+
e);
}
}
那么DaoTransactionManager以什么依据处理事务呢?DaoTransactionState看看DaoTransactionState的代码,非常简单,四个常量来表示事务处于的不同的状态
public
static
final
DaoTransactionState ACTIVE
=
new
DaoTransactionState();
public
static
final
DaoTransactionState INACTIVE
=
new
DaoTransactionState();
public
static
final
DaoTransactionState COMMITTED
=
new
DaoTransactionState();
public
static
final
DaoTransactionState ROLLEDBACK
=
new
DaoTransactionState();
那么实际程序中是如何控制事务的呢
在第一段代码中,我们是这样取得DAO
orderDao = (OrderDao) daoManager.getDao(OrderDao.class);
实际daoManager返回的并不是orderDao的具体实现类,它返回的DaoProxy
DaoProxy
public
Object invoke(Object proxy, Method method, Object[] args)
throws
Throwable
{
Object result
=
null
;
if
(PASSTHROUGH_METHODS.contains(method.getName()))
{
try
{
result
=
method.invoke(daoImpl.getDaoInstance(), args);
}
catch
(Throwable t)
{
throw
ClassInfo.unwrapThrowable(t);
}
}
else
{
StandardDaoManager daoManager
=
daoImpl.getDaoManager();
DaoContext context
=
daoImpl.getDaoContext();
if
(daoManager.isExplicitTransaction())
{
//
Just start the transaction (explicit)
try
{
context.startTransaction();
result
=
method.invoke(daoImpl.getDaoInstance(), args);
}
catch
(Throwable t)
{
throw
ClassInfo.unwrapThrowable(t);
}
}
else
{
//
Start, commit and end the transaction (autocommit)
try
{
context.startTransaction();
result
=
method.invoke(daoImpl.getDaoInstance(), args);
context.commitTransaction();
}
catch
(Throwable t)
{
throw
ClassInfo.unwrapThrowable(t);
}
finally
{
context.endTransaction();
}
}
}
return
result;
}
看到这段代码就非常清楚了,每调用DAO的一次方法时,如果不显式的调用daoManager.startTransaction(),就会成为单独的一个事务。再看看ibatis为我们提供的摸板JdbcDaoTemplate
protected
Connection getConnection()
{
DaoTransaction trans
=
daoManager.getTransaction(
this
);
if
(
!
(trans
instanceof
ConnectionDaoTransaction))
{
throw
new
DaoException(
"
The DAO manager of type
"
+
daoManager.getClass().getName()
+
"
cannot supply a JDBC Connection for this template, and is therefore not
"
+
"
supported by JdbcDaoTemplate.
"
);
}
return
((ConnectionDaoTransaction) trans).getConnection();
}
ibatis控制多个DAO的事务实际是让这些DAO共用了一个DaoTransaction(ThreadLocal),一个Connection
这里是一个事务源的情况,如果多个事务源之间要完成全局事务,还是老老实实用分布式事务管理服务吧(jta)
http://www.blogjava.net/ronghao 荣浩原创,转载请注明出处:)
posted on 2006-01-20 17:50
ronghao
阅读(2315)
评论(4)
编辑
收藏
所属分类:
工作日志
FeedBack:
#
re: ibatis DAO 事务探索
2006-12-06 03:14 |
..
无聊
回复
更多评论
#
re: ibatis DAO 事务探索
2007-02-10 11:58 |
yidinghe
很棒!很有启发性!谢谢!
回复
更多评论
#
re: ibatis DAO 事务探索
2007-07-25 23:43 |
zph
不错,谢谢
回复
更多评论
#
re: ibatis DAO 事务探索
2008-03-26 10:37 |
屹砾
先看一下,我也遇到了这个问题,一个事务操纵多个行为,不过事务总是没有原子性,比较严重。
回复
更多评论
IT新闻
新用户注册
刷新评论列表
标题
姓名
主页
验证码
*
内容(请不要发表任何与政治相关的内容)
Remember Me?
登录
使用高级评论
新用户注册
返回页首
恢复上次提交
[使用Ctrl+Enter键可以直接提交]
相关链接:
网站导航:
博客园
BlogJava
博客生活
IT博客网
C++博客
PHP博客
博客园社区
管理博客
教师博客
天文博客
汽车博客
足球博客
股票博客
电子博客
管理
相关文章:
SNA方案之session炒冷饭
一次性能调优的实战
从贫血到充血Domain Model
高并发测试下的一些问题及解决
failed batch HSQLDB
使用solr搭建你的全文检索
结合spring+hibernate与jdbc的事务
REST个人认知(一)
sqlserver2000下USER表名与系统表重名
关于集群的补课
<
2008年3月
>
日
一
二
三
四
五
六
24
25
26
27
28
29
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
1
2
3
4
5
目前为北京东方易维软件工作流产品经理,专注于工作流的开发。联系方式:ronghao100@hotmail.com
常用链接
我的随笔
我的评论
我的参与
最新评论
留言簿
(20)
给我留言
查看公开留言
查看私人留言
随笔分类
ajax相关(8)
cms(7)
j2se基础(5)
OOA/OOD(4)
SOA、BPM(22)
工作日志(17)
工作流jbpm3(10)
心情小站(21)
权限相关(12)
表现层相关(4)
转载(3)
随笔档案
2008年9月 (2)
2008年8月 (2)
2008年7月 (2)
2008年6月 (3)
2008年5月 (4)
2008年4月 (1)
2008年3月 (2)
2008年2月 (2)
2008年1月 (4)
2007年11月 (3)
2007年10月 (3)
2007年9月 (2)
2007年8月 (4)
2007年7月 (1)
2007年6月 (12)
2007年5月 (2)
2007年4月 (1)
2007年3月 (8)
2007年2月 (6)
2007年1月 (4)
2006年12月 (4)
2006年11月 (3)
2006年10月 (1)
2006年8月 (2)
2006年7月 (3)
2006年6月 (3)
2006年4月 (1)
2006年3月 (2)
2006年2月 (2)
2006年1月 (4)
2005年12月 (7)
2005年11月 (12)
文章分类
Hibernate3
JSP标签
工作流jbpm3(2)
文章档案
2005年11月 (2)
常去的网站
JavaEye
JAVA研究组织
开源大全
搜索
最新评论
1. re: 什么是JAVA内容仓库(Java Content Repository)(1)
挺好
--osw
2. re: jbpm的用户角色管理
ding
--dfsdf
3. re: 一次性能调优的实战
评论内容较长,点击标题查看
--zbl400
4. re: 一次性能调优的实战
怎么能查看 部署的weblogic是运行在32位机器上,还是64位机器?
--bf1977
5. re: 一次性能调优的实战[未登录]
评论内容较长,点击标题查看
--ronghao
阅读排行榜
1. Acegi ACL使用说明(3366)
2. 使用solr搭建你的全文检索(3267)
3. DisplayTag应用(3222)
4. 对Acegi ACL扩展的构想(3076)
5. 结合spring+hibernate与jdbc的事务(2982)
评论排行榜
1. 什么是JAVA内容仓库(Java Content Repository)(2)(23)
2. 高并发测试下的一些问题及解决(22)
3. DisplayTag应用(21)
4. 开始开发CMS(11)
5. 探讨一个可能的大访问量交易网站的开发注意事项(9)