孙卫琴的《精通JPA与Hibernate》的读书笔记:声明JTA事务

Java应用通过JTA API声明JTA事务的步骤如下。

(1)在Hibernate配置文件中配置数据源以及JTA平台属性:

hibernate.connection.datasource= java:comp/env/jdbc/SAMPLEDB 
hibernate.transaction.coordinator_class=jta
hibernate.transaction.jta.platform=JBossTS

(2)在程序中创建javax.naming.InitialContext对象:

Context context=new InitialContext();

(3)在程序中,通过JTA的javax.transaction.UserTransaction接口来声明JTA事务。

以下程序代码声明了一个分布式的事务。entityManagerFactoryBeijing代表运行在北京的一个数据库存储源,entityManagerFactoryShanghai代表运行在上海的一个数据库存储源。entityManager1和entityManager2会分别操纵这两个存储源中的数据。由于entityManager1和entityManager2所做的数据库操作都位于同一个JTA事务中,因此JTA实现会保证这个JTA事务的原子性。

UserTransaction utx=
      (UserTransaction)new InitialContext()
      .lookup("java:comp/UserTransaction");     
EntityManager entityManager1=null;
EntityManager entityManager2=null;

try{
  //声明开始事务
  utx.begin();
 
  entityManager1=entityManagerFactoryBeijing
                                  .createEntityManager();
  entityManager2=entityManagerFactoryShanghai
                                 .createEntityManager();
  
  //通过entityManager1执行一些更新北京数据库的操作
  Account account1=entityManager1
                      .find(Account.class,Long.valueOf(1)); 
  account1.setBalance(account1.getBalance()-100); 

  //通过entityManager2执行一些更新上海数据库的操作
  Account account2=entityManager2
                       .find(Account.class,Long.valueOf(2)); 
  account2.setBalance(account2.getBalance()+100);
  
  entityManager1.flush();  //清理EntityManager1缓存
  entityManager2.flush();  //清理EntityManager2缓存

  //提交事务      
  utx.commit();
}catch (Exception e) {
  if (utx!=null){
    try{ 
       //Status接口位于javax.transaction包中,表示事务状态 
       if ( utx.getStatus() == Status.STATUS_ACTIVE  || 
            utx.getStatus() == Status.STATUS_MARKED_ROLLBACK) {
         utx.rollback();//操作不成功则撤销事务
       }
    }catch(Exception ex){
        log.error("无法撤销事务",ex);  //记录日志
    }
  }

  throw new RuntimeException(e);  //继续抛出异常
}finally {
  try{
    entityManager1.close();
    entityManager2.close();
  }catch(RuntimeException ex){
     log.error("无法关闭EntityManager",ex);  //记录日志
  }
}

以上程序代码演示了一个分布式的转账事务,从位于北京的一个账户中转账100元到上海的一个账户中。JTA实现会保证这个分布式的转账事务的原子性。

默认情况下,通过UserTransaction的commit()方法提交事务时,该方法不会自动清理底层Session的持久化缓存,因此必须在程序中调用EntityManager的flush()方法来手工清理缓存。此外,程序必须在提交事务后手工关闭EntityManager。

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Java技术集锦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值