1、java事务介绍
java事务分类:JDBC事务、JTA(java transaction api) 事务,容器事务,常见的容器事务如:spring事务,容器事务用于j2ee应用服务器中,容器事件大多是基于JTA完成的;本文主要介绍JDBC事务、JTA事务
2、JDBC事务
(1)介绍:JDBC事务主要都是基于Connection对象的进行管理的,常见的和事务相关的方法有:setAutoCommit、commit、rollback等,jdbc事务与数据库的交互如下:
(2)事务示例
(3)优缺点
优点是:简单,不需要依赖应用服务器,只需要实现api即可实现事务,部署简单;
缺点是:一个JDBC不能跨多个数据库(因为一个JDBC事务限定在一个单一的数据库连接),不能用于多数据源和分布式事务中。
3、JTA事务
(1)概念介绍:
JTA是比JDBC更强大的事务,由于JDBC不支持分布式事务,而JTA则可以解决该问题;(分布式事务介绍:一个分布式事务处理包含:JTA和JTS组成;包含了事务管理器(Transaction Manager)和一个或者多个符合XA(XA是X/Open DTP定义的交易中间件和数据库间的接口规范(即接口函数交易中间件用它来通知数据库事务的开始、介绍已经提交,XA接口函数由数据库厂商提供)协议的资源管理器(Resource Manager))
JTA和他的同胞java事务服务(JTS:java transaction service)为J2EE平台提供了分布式事务,但JTA只是提供一个接口,并没有具体的实现,其实现由j2ee服务提供商根据JTS规范提供的,其实现主要有:J2EE容器所提供的JTA实现(JBoss、Tomcat: J2EE中间件)
(2)JTA事务详解
要用JTA事务就要有符合要求的javax.sql.XADataSource 、 javax.sql.XAConnection 和 javax.sql.XAResource;这些接口都必须符合XA协议,XA协议支持分布式事务,而非XA不支持分布式事务;
JTA事务主要的接口为:
java.transaction.UserTransaction ,里面定义了下面几个方法
begin:开启一个事务
commit:提交当前事务
rollback:回滚当前事务
setRollbackOnly:把当前事务标记为回滚
setTransactionTimeout:设置事务的事件,超过这个事件,就抛出异常,回滚事务
示例代码:
publicvoidJtaTransfer() {
javax.transaction.UserTransactiontx=null;
java.sql.Connectionconn=null;
try{
tx=(javax.transaction.UserTransaction)context.lookup("java:comp/UserTransaction");//取得JTA事务,本例中是由Jboss容器管理
javax.sql.DataSourceds=(javax.sql.DataSource)context.lookup("java:/XAOracleDS");//取得数据库连接池,必须有支持XA的数据库、驱动程序
tx.begin();
conn=ds.getConnection();
// 将自动提交设置为 false,
//若设置为 true 则数据库将会把每一次数据更新认定为一个事务并自动提交
conn.setAutoCommit(false);
stmt=conn.createStatement();
// 将 A 账户中的金额减少 500
stmt.execute("\
update t_account set amount = amount - 500 where account_id = 'A'");
// 将 B 账户中的金额增加 500
stmt.execute("\
update t_account set amount = amount + 500 where account_id = 'B'");
// 提交事务
tx.commit();
// 事务提交:转账的两步操作同时成功
}catch(SQLExceptionsqle){
try{
// 发生异常,回滚在本事务中的操做
tx.rollback();
// 事务回滚:转账的两步操作完全撤销
stmt.close();
conn.close();
}catch(Exceptionignore){
}
sqle.printStackTrace();
}
}
(3)优缺点
优点:解决了分布式事务;
缺点:JTA只在应用服务器环境下使用,且JTA只是Java提供的统一分布式api,不同的应用服务器有不同的实现;因此使用JTA会限制代码的复用性;而且JTA 的UserTransaction需要从JNDI中获取,那么如果要使用JTA就需要使用JTA和JNDI;
转载:http://www.hollischuang.com/archives/1658