Java事务管理整理

来源:互联网 发布:linux 多线程 connect 编辑:程序博客网 时间:2024/06/06 02:48


可以从以下两个方面来学习了解Java的事务管理:
•Java事务管理:提供了JDBC事务和JTA事务
•EJB事务管理:是基于JTA事务的实现,包括手工管理和容器管理两种方式,手工管理使用事务管理类EntityTransaction进行控制,容器管理使用注释符@TransactionAttribute来进行标。

一、Java事务管理机制

    两种管理技术:JDBC事务、JTA(Java Transaction API)事务。
•JDBC事务可以运行在任意的Java容器、Web服务器和JavaEE应用服务器中。
•JTA事务通常由容器进行管理,所以通常都会运行在JavaEE应用服务器,例如JBoss、WebSphere、WebLogic等。

    在运用以上两种事务之前,首先注意以下事务使用的基本准则:
•不要在程序中同时使用上述两种事务类型。
•事务要尽可能短的时间内完成,不要在不同方法中实现事务的使用。
•事务管理可以进行嵌套,但事务的嵌套要求精良的设计。

    下面我们来看看JDBC事务、JTA事务的管理机制,并学习基于JTA实现的服务:JTS事务服务。

    1.1JDBC事务管理机制

    JDBC事务由Connection管理,实际上是在JDBC连接对象Connection中实现的,周期限于Connection的生命周期之内。

     java.sql.Connection类提供了两种事务模式:
•自动提交:在JDBC中事务操作默认采用的是自动提交,
 即一个对数据库的更新表达式代表一项事务操作,操作成功后系统将自动调用commit()来提交,否则将调用rollback()来回滚。
•手工提交:在JDBC中,可以通过调用setAutoCommit(false)来禁止自动提交。
之后可以把多个数据库操作的代码作为一个事务,在操作完成 后调用commit()来进行整体提交。如果其中一个操作失败将不会执行commit(),并会抛出一个异常。
此时可以在异常截获时调用 rollback()进行回滚。保证多次更新操作后相关数据的一致性。

    下面是进行手工提交的程序实例 :
 Connection conn = null;
  Statement stmt = null;
  try{
 //禁止自动提交
   conn.setAutoCommit(false);

   stmt = conn.createStatement();
   //插入数据操作
   stmt.executeUpdate("insert into(username,password,email) user values('admin','admin','admin@123.com')");
   //更新数据操作
   stmt.executeUpdate("update user set email='admin@163.com'");
 
   //事务提交
   conn.commit();

  }catch(Exception ex){
   try{

    //事务回滚
    conn.rollback();
   }catch(Exception e){
    e.printStackTrace();
   }
  }finally{
   //关闭连接
   if(conn != null){
    try{
     conn.close();
    }catch(Exception e){
     e.printStackTrace();
    }
   }
  }

设置回滚点
Connection conn = null;
PreparedStatement ps1 = null;
PreparedStatement ps2 = null;
Savepoint sp = null;

try{
//禁止自动提交
conn.setAutoCommit(false);

ps1 = conn.prepareStatement("update account set money = money+100 where name=?");
ps1.setString(1, "b");
ps1.executeUpdate();

ps2 = conn.prepareStatement("update account set money = money-100 where name=?");
ps2.setString(1, "a");
ps2.executeUpdate();

//设置会滚点
sp = conn.setSavepoint();

ps1 = conn.prepareStatement("update account set money = money+100 where name=?");
ps1.setString(1, "b");
ps1.executeUpdate();

ps2 = conn.prepareStatement("update account set money = money-100 where name=?");
ps2.setString(1, "a");
ps2.executeUpdate();

 //事务提交
conn.commit();

}catch (Exception e) {

e.printStackTrace();

try {

if(sp !=null){
//事务回滚到指定点
conn.rollback(sp);
conn.commit();

}else{
//事务回滚
conn.rollback();
}

} catch (SQLException e1) {

e1.printStackTrace();
}

}finally{

DaoUtil.close(conn, ps1, null);
DaoUtil.close(conn, ps2, null);
}
}
}


以上代码中,加粗部分表示了事务控制的3个不同阶段。
•begin():开始一个事务,接下来所有SQL查询的更新都将在控制之内。
•commit():对以上所有操作进行事务提交,更新数据库。
•rollback():如果以上操作中某一个出现异常,那么回滚之前的所有操作,不影响数据库中的数据。

  上述这种方法是最为简单和直接的事务控制,可以很清晰的控制多个SQL语句,这些语句可以代表用户的一次操作。
  但是这种方法只能够对一个Connection对象进行事务控制,也就是说不能同时处理多个数据库的事务,JTA的方式则可以解决这个问题。


其他的参考:

Java事务管理学习一 -- JDBC的事务控制

Java事务管理学习二 -- JTA的事务管理机制



原创粉丝点击