Chinaunix首页 | 论坛 | 博客
  • 博客访问: 438704
  • 博文数量: 161
  • 博客积分: 5005
  • 博客等级: 上校
  • 技术积分: 1090
  • 用 户 组: 普通用户
  • 注册时间: 2008-10-20 16:38
文章分类

全部博文(161)

文章存档

2011年(21)

2010年(33)

2009年(89)

2008年(18)

我的朋友

分类: Java

2009-03-30 14:19:04

本文章很扫盲,有几个概念在这里更容易理解一些,好文特此收藏。

一、事务

事务是一个非常重要的编程概念,使用事务,可以很简单地构造出可靠稳定的应用程序,尤其对那些需要进行并发数据访问的应用程序,事务更是重要的多。

使用事务,便可以利用事务的四个重要属性:ACID。

* 原子性( atomic):事务中包含的各项操作必须全部成功执行或者全部不执行。任何一项操作失败,将导致整个事务失败,其他已经执行的任务所作的数据操作都将被撤销,只有所有的操作全部成功,整个事务才算是成功完成。

* 一致性( consistent):保证了当事务结束后,系统状态是一致的。那么什么是一致的系统状态?例如,如果银行始终遵循着"银行账号必须保持正态平衡"的原 则,那么银行系统的状态就是一致的。上面的转账例子中,在取钱的过程中,账户会出现负态平衡,在事务结束之后,系统又回到一致的状态。这样,系统的状态对 于客户来说,始终是一致的。

* 隔离性( isolated):使得并发执行的事务,彼此无法看到对方的中间状态。保证了并发执行的事务顺序执行,而不会导致系统状态不一致。

* 持久性( durable):保证了事务完成后所作的改动都会被持久化,即使是发生灾难性的失败。可恢复性资源保存了一份事务日志,如果资源发生故障,可以通过日志来将数据重建起来。

二、事务界定

两种事务界定的模型
* 声明式事务界定
* 编程式事务界定

三、设计DAO时需要考虑的问题

* 事务要如何开始?
* 事务应如何结束?
* 哪一个对象将负责开始一个事务?
* 哪一个对象将负责结束一个事务?
* DAO是否要负责事务的开始和结束?
* 应用程序是否需要通过多个DAO访问数据?
* 事务涉及到一个DAO还是多个DAO?
* 一个DAO是否调用另一个DA 的方法?

了解上述问题的答案将有助于选择最适合的DAO的事务界定策略。在DAO中有两种主要的界定事务的策略。一种方式是让DAO负责界定事务,另一种将事务界定交给调用这个DAO方法的对象处理。

如果选择了前一种方式,那么就将事务代码嵌入到DAO中。如果选择后一种方式,那么事务界定代码就是在DAO类外面。对于需要在一个事务中访问多个DAO的应用程序应该使用第二中策略。


四、事务界定两种实现方式

JTA事务和JDBC事务

1.JTA事务
JTA是一种不受实施限制的高层协议API,该协议API使应用程序和应用服务器可以访问事务。JTA属于全局事务,由应用服务器管理(Tomcat需要结合JOTM(Java Open Transaction Manager)来支持事务),使用JTA的同时需要使用JNDI。

JTA及其同门兄弟JTS为 J2EE 平台提供了分布式事务服务。一个分布式的事务涉及一个事务管理器和一个或者多个资源管理器。一个资源管理器是任何类型的持久性的数据存储。事务管理器负责协调所有事务参与者之间的通信。

JTA事务比JDBC事务功能更强。JDBC事务局限为一个数据库连接,而JTA事务可以有多个参与者。所有下列Java平台组件都可以参与JTA事务:
* JDBC 连接
* JDO PersistenceManager 对象
* JMS 队列
* JMS 主题
* 企业 JavaBeans
* 符合 J2EE 连接体系结构(J2EE Connector Architecture)规范的资源适配器

要用JTA进行事务界定,应用程序要调用javax.transaction.UserTransaction接口中的方法:
* public void begin()
* public void commit()
* public void rollback()
* public int getStatus()
* public void setRollbackOnly()
* public void setTransactionTimeout(int)

[代码示例:JTA进行事务界定]
import javax.transaction.*;
import javax.naming.*;
// ...
InitialContext ctx = new InitialContext();
Object txObj = ctx.lookup("java:comp/UserTransaction");
UserTransaction utx = (UserTransaction) txObj;

utx.begin();
// ...
DataSource ds = obtainXADataSource();
Connection conn = ds.getConnection();
pstmt = conn.prepareStatement("Update MOVIES ...");
pstmt.setString(1, "Spinal Tap");
pstmt.executeUpdate();
// ...
utx.commit();
// ...
[/代码示例]


2.JDBC事务
JDBC事务受数据库的事务管理器控制。JDBC事务属于本地事务,它容易使用,但是存在缺点:它们不能用于多个事务性资源,也就是事务的范围局限于一个数据库连接,一个JDBC事务不能跨越多个数据库。另一个缺点是局部事务趋向于入侵式的编程模式。

JDBC事务是用Connection对象控制的。JDBC Connection接口( java.sql.Connection )提供了两种事务模式:自动提交和手工提交。java.sql.Connection 提供了以下控制事务的方法:
* public void setAutoCommit(boolean)
* public boolean getAutoCommit()
* public void commit()
* public void rollback()

[代码示例:用JDBC API进行事务界定]
import java.sql.*;
import javax.sql.*;

// ...
DataSource ds = obtainDataSource();
Connection conn = ds.getConnection();
conn.setAutoCommit(false);
// ...
pstmt = conn.prepareStatement("Update MOVIES ...");
pstmt.setString(1, "The Great Escape");
pstmt.executeUpdate();
// ...
conn.commit();
// ...
[/代码示例]


JDBC支持的四种事务隔离模式(transaction isolation mode)。

3.JTA和JDBC
用JTA界定事务,那么就需要有一个实现javax.sql.XADataSource、javax.sql.XAConnection和 javax.sql.XAResource接口的JDBC驱动程序。一个实现了这些接口的驱动程序将可以参与JTA事务。一个XADataSource对 象就是一个XAConnection对象的工厂。XAConnections是参与JTA事务的JDBC连接。

并需要用应用服务器的管理工具设置XADataSource。J2EE应用程序用JNDI查询数据源。一旦应用程序找到了数据源对象,它就调用javax.sql.DataSource.getConnection()以获得到数据库的连接。

XA连接与非XA连接不同。一定要记住XA连接参与了JTA事务。这意味着XA连接不支持JDBC的自动提交功能。同时,应用程序一定不要对XA连接调用 java.sql.Connection.commit()或者java.sql.Connection.rollback()。相反,应用程序应该使用 UserTransaction.begin()、UserTransaction.commit()和 UserTransaction.rollback() 。

三、Spring、Hibernate和iBatis

这三个框架都有通过JDBC事务界定的方式实现事务管理。但相比之下,Spring在事务管理方面是其中最成熟的。

1.Spring
Spring Framework实际上是Expert One-on-One J2EE Design and Development一书中所阐述的设计思想的具体实现。
Spring Framework的功能非常多。包含AOP、ORM、DAO、Context、Web、MVC等几个部分组成。但其中最需要用的是AOP、ORM、 Context。Context中,最重要的是Beanfactory,它能将接口与实现分开,非常强大。前AOP应用最成熟的还是在事务管理上。

2.Hibernate
Spring框架已经提供了对Hibernate框架的良好支持,因此不再需要再头痛于Hibernate的session管理,事务管理等方面,这些Spring框架已经进行了很好的封装。

3.ibatis
ibatis不熟悉,如果你对ibatis的事务管理比较熟悉,请告诉我如何ibatis的实现方式:)

四、推荐阅读

事务管理最佳实践全面解析
http://dev.csdn.net/author/shendl/7098537bcd8b436197cd7e959936a911.html

事务管理最佳实践多余的话之一
http://dev.csdn.net/author/shendl/4fe0df2717bd47d8b73b31a16f38d1bb.html

事务管理最佳实践多余的话之二
http://dev.csdn.net/author/shendl/7fc1c42ab0a6433eab061943bb380dcf.html

事务管理最佳实践多余的话之三
http://dev.csdn.net/author/shendl/f4f97546410a4653949ba8ae837c4383.html

集成 Hibernate,Spring,Struts Portlet 框架构建Portlet应用
http://www-128.ibm.com/developerworks/cn/websphere/library/techarticles/guorui/

基于struts+spring+ibatis的轻量级J2EE开发
http://www-128.ibm.com/developerworks/cn/java/j-s-s-i/

在Jstl+Spring+ibatis开发中应用事务管理经验总结
http://blog.donews.com/yarak/archive/2006/04/25/845534.aspx


[附录1:参考文献]

使用Enterprise Bean处理事务,

----
事务服务浅析
http://www-128.ibm.com/developerworks/cn/java/l-transation/part1/
http://www-128.ibm.com/developerworks/cn/java/l-transation/part2/
----
高级DAO编程
http://www-128.ibm.com/developerworks/cn/java/j-dao/
----
基于JDBC的数据库连接池高效管理策略
http://www-128.ibm.com/developerworks/cn/java/l-jdbcperform/
----
Spring 事务管理

----
分析Hibernate的事务处理机制

----
集成 Hibernate,Spring,Struts Portlet 框架构建Portlet应用
http://www-128.ibm.com/developerworks/cn/websphere/library/techarticles/guorui/
----
基于struts+spring+ibatis的轻量级J2EE开发
http://www-128.ibm.com/developerworks/cn/java/j-s-s-i/
----
在Jstl+Spring+ibatis开发中应用事务管理经验总结
http://blog.donews.com/yarak/archive/2006/04/25/845534.aspx
----
How to use JDBC and transactions in Tomcat with JOTM
http://jotm.objectweb.org/current/jotm/doc/howto-tomcat-jotm.html


[附录2:缩写列表]
DAO - Data Access Object
JTA - Java Transaction API
JTS - Java Transaction Service (Java事务服务)
JDBC - Java Database Connectivity

阅读(1074) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~