一、前言
今天中午一小伙伴在进行JPA的相关配置时遇到一些疑惑点,自己思考了一下也没有搞明白,就查了一些资料,翻看了之前的一些代码,逐渐搞明白了几点。写一博客分享之。
二、UserTransaction简析
2.1 代码展示
请看下面一段代码:
1.注意看javax.transaction.UserTransaction
import javax.transaction.UserTransaction;
@Inject
private UserTransaction utx;
2.注意看UserTransaction的实例化方式
private UserTransaction utx = entityManager.getTransaction();
2.2 官方文档解析
UserTransaction的Java EE6官方文档是这样定义的:
The UserTransaction interface defines the methods that allow an
application to explicitly manage transaction boundaries.
UserTransaction
接口定义的方法允许应用程序显式地管理事务边界。
换言之,UserTransaction是Java EE中用来进行事务管理的一个接口。
其主要实现方法有如下几个:
begin()
getStatus()
rollback()
setRollbackOnly()
setTransactionTimeout(int seconds)
三、JPA中的事务管理
3.1 事务管理相关概念理解
事务的概念:
事务是应用程序中一系列严密的操作的集合,也就是两个及两个以上操作的集合。事务的特点是,所有操作必须成功完成,否则在每个操作中所作的所有更改都会被撤消。也就是事务具有原子性,一个事务中的一系列的操作要么全部成功,要么一个都不做。
同时也就意味着事务的结束有两种,当事务中的所以步骤全部成功执行时,事务提交。如果其中一个步骤失败,将发生回滚操作,撤消撤消之前到事务开始时的所以操作。
事务机制的优势:
使用事务机制的好处非常明显,例如银行转账之类的交易操作中,事务有着重要的作用。事务的成功取决于事务单元帐户相互依赖的操作行为是否能全部执行成功,只要有一个操作行为失败,整个事务将失败。例如:客户A和客户B的银行账户金额都是10000元人民币,客户A需要把自己帐户中的5000元人民币转到客户B的账户上。这个过程看似简单,实际上涉及了一系列的数据库操作,可以简单地视为两步基本操作,即从客户A帐户的金额中扣除5000元人民币,以及将客户B帐户中金额添加5000元人民币。假设第1步数据库操作成功,而第二步失败的话,将导致整个操作失败,并且客户A帐户金额将被扣除5000元人民币。事务机制可以避免此类情况,以保证整个操作的完成,如果某步操作出错,之前所作的数据库操作将全部失效。
3.2 JPA中的事务管理
在JPA中,JPA本身没有提供任何类型的声明式事务管理,所以,为了更好的进行一系列的事务操作和管理,常用的事务管理有容器管理和人为管理。人为管理需要代码实现。
在JPA中一种实现方式就是调用entityManager的UserTransaction。即:
UserTransaction utx = entityManager.getTransaction();
3.3 JPA中UserTransaction与entityManager的关系
上述UserTransaction接口由entityManager对象实现,例如:
// 实例化对象
UserTransaction utx = entityManager.getTransaction();
// 开启事务
utx.begin();
// 提交事务
utx.commit();
四、实例代码展示
4.1 个人代码
package cn.edu.sdut.softlab.controller;
import javax.enterprise.context.RequestScoped;
import javax.inject.Named;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.transaction.HeuristicMixedException;
import javax.transaction.HeuristicRollbackException;
import javax.transaction.RollbackException;
import javax.transaction.SystemException;
import javax.transaction.UserTransaction;
import cn.edu.sdut.softlab.model.Person;
@Named("controller")
@RequestScoped
public class PersonController {
//定义全局变量
EntityManagerFactory emf = null;
EntityManager em = null;
//引入UserTransaction
private UserTransaction utx;
private Person newPerson = new Person();
// newPerson的getter和setter方法
public Person getNewPerson() {
return newPerson;
}
public void setNewPerson(Person newPerson) {
this.newPerson = newPerson;
}
// login方法
public void addPerson() throws IllegalStateException, SecurityException, HeuristicMixedException,
HeuristicRollbackException, RollbackException, SystemException {
try {
//utx.begin();
//该参数必须与persistence-unit的name相一致
emf = Persistence.createEntityManagerFactory("PersonUnit");
em = emf.createEntityManager();
// 断点测试
System.out.println("打印输出newPerson: " + newPerson.toString());
System.out.println("打印输出em: " + em.toString());// 测试结果,EntityManager注入失败
em.getTransaction().begin();// 至关重要的一步:开启事务
em.persist(newPerson);
em.getTransaction().commit();
} catch (Exception e) {
e.printStackTrace();
} finally {
em.close();
emf.close();
//utx.commit();
System.out.println("存入成功!");
}
}
}
4.2 详细完整代码
请移步:https://github.com/GaoZiqiang/HelloWorldJPADemo
五、待解决问题
@Inject
private UserTransaction utx;
这段代码中的utx对象是如何实例化的?