我的博客中曾经关于事务有过许多接头,软件开发,之前的事务先容根基都是数据库层面的事务,本文来先容一下J2EE中和事务相关的内容,在阅读本文之前,但愿读者对漫衍式有必然的相识。
关于事务的基本常识这里不再具体先容,想要相识的同学可以在我的博客中阅读相关文章。
Java事务的范例有三种:JDBC事务、JTA(Java Transaction API)事务、容器事务。 常见的容器事务如Spring事务,容器事务主要是J2EE应用处事器提供的,容器事务大多是基于JTA完成,这是一个基于JNDI的,相当巨大的API实现。所以本文暂不接头容器事务。本文主要先容J2EE开拓中两个较量根基的事务:JDBC事务和JTA事务。
JDBC事务
JDBC的一切行为包罗事务是基于一个Connection的,在JDBC中是通过Connection工具举办事务打点。在JDBC中,常用的和事务相关的要领是: setAutoCommit、commit、rollback等。
下面看一个简朴的JDBC事务代码:
public void JdbcTransfer() { java.sql.Connection conn = null; try{ conn = conn =DriverManager.getConnection("jdbc:oracle:thin:@host:1521:SID","username","userpwd"); // 将自动提交配置为 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'"); // 提交事务 conn.commit(); // 事务提交:转账的两步操纵同时乐成 } catch(SQLException sqle){ try{ // 产生异常,回滚在才干务中的操做 conn.rollback(); // 事务回滚:转账的两步操纵完全取消 stmt.close(); conn.close(); }catch(Exception ignore){ } sqle.printStackTrace(); } }
上面的代码实现了一个简朴的转账成果,通过事务来节制转账操纵,要么都提交,要么都回滚。
JDBC事务的优缺点
JDBC为利用Java举办数据库的事务操纵提供了最根基的支持。通过JDBC事务,我们可以将多个SQL语句放到同一个事务中,担保其ACID特性。JDBC事务的主要利益就是API较量简朴,可以实现最根基的事务操纵,机能也相对较好。
可是,劳务派遣管理系统,JDBC事务有一个范围:一个 JDBC 事务不能超过多个数据库!!!所以,假如涉及到大都据库的操纵可能漫衍式场景,JDBC事务就无能为力了。
JTA事务
为什么需要JTA
凡是,JDBC事务就可以办理数据的一致性等问题,鉴于他用法相对简朴,所以许多人关于Java中的事务只知道有JDBC事务,可能有人知道框架中的事务(好比Hibernate、Spring)等。可是,由于JDBC无法实现漫衍式事务,而如今的漫衍式场景越来越多,所以,JTA事务就应运而生。
假如,你在事情中没有碰着JDBC事务无法办理的场景,那么只能说你做的项目还都太小。拿电商网站来说,我们一般把一个电商网站横向拆分成商品模块、订单模块、购物车模块、动静模块、付出模块等。然后我们把差异的模块陈设到差异的呆板上,各个模块之间通过长途处事挪用(RPC)等方法举办通信。以一个漫衍式的系统对外提供处事。
一个付出流程就要和多个模块举办交互,每个模块都陈设在差异的呆板中,而且每个模块操纵的数据库都纷歧致,这时候就无法利用JDBC来打点事务。我们看一段代码:
/** 付出订单处理惩罚 **/ @Transactional(rollbackFor = Exception.class) public void completeOrder() { orderDao.update(); // 订单处事当地更新订单状态 accountService.update(); // 挪用资金账户处事给资金帐户加款 pointService.update(); // 挪用积分处事给积分帐户增加积分 accountingService.insert(); // 挪用管帐处事向管帐系统写入管帐原始凭证 merchantNotifyService.notify(); // 挪用商户通知处事向商户发送付出功效通知 }
上面的代码是一个简朴的付出流程的操纵,个中挪用了五个处事,这五个处事都通过RPC的方法挪用,请问利用JDBC如何担保事务一致性?我在要领中增加了@Transactional注解,可是由于回收挪用了漫衍式处事,该事务并不能到达ACID的结果。