005 事务——分本地事务和分布式事务哦~

1.8 事务

事务是Web应用中不可缺少的组件模型,它保证了用户操作的原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、和持久性(Durabilily).事务分本地事务和分布式事务两种。

1.8.1 本地事务

本地事务基于数据库资源实现,事务穿心地在JDBC连接上执行,本地事务将事务处理局限在当前事务资源内。其特点是使用灵活但无法支持多数据源事务操作。在数据库连接池中使用本地事务的代码
示例如下。

public void transferAccount(){
  Connection conn = null;
  Statement stmt = null;
  try{
    conn = getDataSource().getConnection();
    //step 1:将自动提交设置为false
    //若设置为true,则数据库将会把每一次数据更新认定为一个事务自动提交
    conn.setAutoCommit(false);
    stmt = conn.createStatement();
    //step 2:操作A数据:将A账户中的金额减少500
    stmt.execute("update t_account set amount = amount + 500 where account_id = 'B'");
    //step 3:操作B数据:将B账户中的金额减少500
    stmt.execute("update t_account set amount = amount + 500 where account_id = 'B'");
    //step 4:提交事务
    conn.commit();
    //转换的两步操作同时执行
    System.out.printlinc("transaction success");
  } catch(SQLException sqle){
    // step 5:异常回滚: 发生异常,回滚在本事务中的操作
    conn.rollback();
    // step 6:关闭并释放数据库资源
    stmt.close();
    conn.close();
  }
}

在上述代码中,shou先通过conn.setAutoCommit(false)设置数据库为非自动提交,然后分别提交了两条更新语句,最后通过conn.commit()提交事务。如果
数据库操作成功,则事务完成;如果操作失败,则通过conn.rollback()回滚事务

1.8.2分布式事务

分布式事务(Distributed Transaction)提供了跨数据库的分布式事务操作的数据一致性,跨数据库的一致性包含同一类型数据库的多个数据库实例服务的一致性(例如多个MySQL的事务一致性)和多个不同类型数据库的数据一致性(例如MySQL和Oracle之间的事务一致性)两种情况。
java事务编程接口(Java Transaction API,JTA)和Java事务服务(Java TransactionServices,JTS)为J2EE平台提供了分布式事务服务。分布式事务包括一个事务管理器(Transaction Manager)和一个或多个XA协议(XA协议是由X/Open组织提出的分布式事务的规范,XA规范主要定义了事务管理器和资源管理器之间的接口)的资源管理(Resource Manager).其中,事务管理器负责所有事务参与安远的协调与控制,资源管理器负责不同的数据库具体的事务执行操作。具体使用代码如下:

public void transferAccount(){
  UserTransaction userTx = null;
  // step 1:定义A、B数据库连接
  Connection connA = null; Statement stmtA = null;
  Connection connB = null; Statement stmtB = null;
  try{
    // step 2:获得Transaction管理对象
    userTx = (UserTransaction)getContext().lookup("java:comp/UserTransaction");
    connA = getDataSourceA().getConnection(); // step 3.1: 从数据库A中取得数据库连接
    connB = getDataSourceB().getConnection(); // step 3.2:从数据库B中取得数据库连接
    userTx.begin(); // step 4.启动事务
    stmtA = connA.createStatement(); 
    //step 5.1:操作A数据库: 将A账户中的金额减少500
    stmtA.execute("update t_account set amount = amount - 500 where account_id = 'A'");
    //step 5.2:.操作B数据库: 将A账户中的金额增加500   
    stmtB = connB.createStatement(); 
    stmtA.execute("update t_account set amount = amount + 500 where account_id = 'B'");
    // step 6:
    userTx.commit();  
    // 提交事务: 转账的两步操作同时执行(数据库A和数据库B中的数据被同时更新)
  }catch(SQLException sqle){
     // step 7:回滚事务,发生异常,回滚在本事务中的操作
     userTx.rollback(); // 数据库A和数据库B中的数据更新被同时撤销
  }

在上述代码中,首先定义了一个分布式事务管理器UserTransaction,然后定义了2个连接池connA和connB,接着通过userTx.begin()启动事务并向两个数据库连接提交2个更新请求,最后通过userTx.commit()统一提交事务。如果执行成功,则事务成功;如果失败,则通过userTx.rollback()回滚事务。

posted @ 2022-10-01 21:01  ╰(‵□′)╯  阅读(35)  评论(0编辑  收藏  举报