Java 处理事务精要

原创 2007年10月11日 19:27:00
简单事务的概念

  我不想从原理上说明什么是事务,应为那太枯燥了。我只想从一个简单的例子来说明什么是事务。

  例如我们有一个订单库存管理系统,每一次生成订单的同时我们都要消减库存。通常来说订单和库存在数据库里是分两张表来保存的:订单表,库存表。每一次我们追加一个订单实际上需要两步操作:在订单表中插入一条数据,同时修改库存的数据。

  这样问题来了,例如我们需要一个单位为10的订单,库存中有30件,理想的操作是我们在订单表中插入了一条单位为10的订单,之后将库存表中的数据修改为20。但是有些时候事情并不是总是按照你的想法发生,例如:在你修改库存的时候,数据库突然由于莫名其妙的原因无法连接上了。也就是说库存更新失败了。但是订单已经产生了,那么怎么办呢?没办法,只有手动的修改。所以最好的方式是将订单插入的操作和库存修改的操作绑定在一起,必须同时成功或者什么都不做。这就是事务。

  Java如何处理事务呢?

  我们从java.sql.Connection说起,Connection表示了一个和数据库的链接,可以通过Connection来对数据库操作。在通常情况是Connection的属性是自动提交的,也就是说每次的操作真的更新了数据库,真的无法回退了。针对上述的例子,一旦库存更新失败了,订单无法回退,因为订单真的插入到了数据库中。这并不是我们希望的。

  我们希望的是:看起来成功了,但是没有真的操作数据库,知道我想让他真的发生。可以通过Connection的setAutoCommit(false)让Connection不自动提交你的数据,除非你真的想提交。那么如何让操作真的发生呢?可以使用Connection的commit方法。如何让操作回退呢?使用rollback方法。

  例如:

  try{

  Connection conn = getConnection(); // 不管如何我们得到了链接

  conn.setAutoCommit(false);

  // 插入订单

  // 修改库存

  conn.commit(); // 成功的情况下,提交更新。

  } catch(SQLException ex) {

  conn.rollback(); // 失败的情况下,回滚所有的操作

  } finally {

  conn.close();

  }

  这里有一点非常重要,事务是基于数据库链接的。所以在但数据库的情况下,事务操作很简单。

  那么如果表分布在两个不同的数据库中呢?

  例如订单表在订单库中,库存表在库存库中,那么我们如何处理这样的事务呢?

  需要注意,提交也可以遇到错误呀!

  try{

  Connection conn1 = getConnection1();

  Connection conn2 = getConnection2();

  // 基于conn1做插入操作

  // 基于conn2做更新操作

  try{

  conn1.commit()

  } catch(SQLExcetion ) {

  conn1.rollback();

  }

  try {

  conn2.commit();

  } catch(SQLException ) {

  conn2.rollbakc();

  // 保证肯定删除刚才插入的订单。

  }

  } catch(SQLException ex) {

  // 如果插入失败,conn1.rollback

  // 如果更新失败,conn1.rollback && conn2.rollback

  } finally {

  conn1.close();

  conn2.close();

  }

  看看上述的代码就知道,其实操作非常的复杂,甚至:保证肯定删除刚才插入的订单根本无法保证。

  在上述情况下的事务可以称之为分布式事务,通过上述的代码中事务同时提交处理的部分我们可以得出,要想处理分布式事务,必须有独立于数据库的第三方的事务处理组件。

  幸运的是通常情况下,JavaEE兼容的应用服务器,例如:Weblogic,Websphere,JBoss,Glassfish等都有这种分布式事务处理的组件。

  如何使用应用服务器的分布式事务管理器处理分布式事务?

  以galssfish为例

  1 建立对应两个数据库的XA(javax.sql.XADataSource)类型的数据源。

  2 使用UserTransaction来保证分布式事务。

  try{

  Connection conn1 = datasource1.getConnection();

  Connection conn2 = datasource2.getConnection();

  UserTransaction ut = getUserTransaction();

  ut.begin();

  // 插入订单

  // 修改库存

  ut.commit(); // 成功的情况下,提交更新。

  } catch(SQLException ex) {

  ut.rollback(); // 失败的情况下,回滚所有的操作

  } finally {

  conn.close();

  }

  如何获取UserTransaction呢?可以使用如下方法

  UserTransaction tx = (UserTransaction)

  ctx.lookup("jndi/UserTransaction"); 

Flash的文字颜色渐变动画

    1、在第一帧上用文字工具随便输几个字,如“中国人”,选好字体、颜色、大小。    2、按Ctrl+B将文字打散(变成图形)。    3、在第十帧建一关键帧。    4、单击时间轴第一帧,选中第...
  • zhangjian80
  • zhangjian80
  • 2001-07-09 11:55:00
  • 8880

unity shader 入门精要 高清完整版PDF下载

  • 2016年12月07日 09:16
  • 48B
  • 下载

Android开发精要(完整书签版).pdf

  • 2014年03月22日 22:41
  • 17.3MB
  • 下载

《JavaScript面向对象精要》

这本书应该是 14 年(或15年)买的,那时人比较傻,看不明白,匆匆看了几十页就束之高阁了,但是一有点很确定,这是本好书。今天终于来到了这里,感觉过了一道坎。引用类型就是对象,对象就是引用类型类型分原...
  • wozaixiaoximen
  • wozaixiaoximen
  • 2017-01-08 15:34:49
  • 549

面向对象JavaScript精要(英文原版pdf)

  • 2017年02月10日 14:16
  • 2.06MB
  • 下载

Unity Shader入门精要

  • 2016年12月01日 13:03
  • 57B
  • 下载

java处理事务

介绍在Java中进行事务处理的方法,通过实例分别讲述了如何采用JavaBean、Ejb组件实现J2EE应用服务器支持的JDBC事务、JTA(Java Transaction API)事务 Java中的...
  • sprita1
  • sprita1
  • 2014-08-20 21:12:32
  • 522

015_《Delphi精要》(附书源码)

  • 2010年11月22日 16:01
  • 766KB
  • 下载

Java事务处理小结

典型的数据库jdbc中的事务处理: ACID (原子性、一致性、孤立性和持久性);在进行数据库”锁”操作时可以选择不同的事务分离水平:1>.READ UNCOMMITTED    效率高,但可能会有脏...
  • Rick100
  • Rick100
  • 2006-02-26 23:27:00
  • 4493

Kotlin程序开发入门精要-压缩包

  • 2018年02月05日 14:52
  • 3.41MB
  • 下载
收藏助手
不良信息举报
您举报文章:Java 处理事务精要
举报原因:
原因补充:

(最多只允许输入30个字)