Join Transaction

The EntityManager.joinTransaction() API allows an application managed EntityManager to join the active JTA transaction context. This allows an EntityManager to be created outside the JTA transaction scope and commit its changes as part of the current transaction. This is normally used with a stateful SessionBean, or with a JSP or Servlet where an EXTENDED EntityManager is used in a stateful architecture. A stateful architecture is one where the server stores information on a client connection until the client's session is over, it differs from a stateless architecture where nothing is stored on the server in between client requests (each request is processed on its own).

There are pros and cons with both stateful and stateless architectures. One of the advantages with using a stateful architecture and and EXTENDED EntityManager, is that you do not have to worry about merging objects. You can read your objects in one request, let the client modify them, and then commit them as part of a new transaction. This is where joinTransaction would be used. One issue with this is that you normally want to create the EntityManager when there is no active JTA transaction, otherwise it will commit as part of that transaction. However, even if it does commit, you can still continue to use it and join a future transaction. You do have to avoid using transactional API such as merge or remove until you are ready to commit the transaction.

joinTransaction is only used with JTA managed EntityManagers (JTA transaction-type in persistence.xml). For RESOURCE_LOCAL EntityManagers you can just commit the JPA transaction whenever you desire.

Example joinTransaction usage

EntityManager em = getEntityManagerFactory().createEntityManager();
Employee employee = em.find(Employee.class, id);
employee.setSalary(employee.getSalary() + 1000); UserTransaction transaction = (UserTransaction)new InitialContext().lookup("java:comp/UserTransaction");
transaction.begin();
em.joinTransaction();
transaction.commit();

参考:https://en.wikibooks.org/wiki/Java_Persistence/Transactions

1.示例

@Stateful
public class ShoppingCartImpl implements ShoppingCart {
@PersistenceUnit
private EntityManagerFactory emf;
private EntityManager em;
private Order order;
private Product product;
@PostConstruct
public void init() {
em = emf.createEntityManager();
}
public void initOrder(Long id) {
order = em.find(Order.class, id);
}
public void initProduct(String name) {
product = (Product) em.createQuery("select p from Product p
where p.name = :name")
.setParameter("name", name)
.getSingleResult();
}
public LineItem createLineItem(int quantity) {
em.joinTransaction();
LineItem li = new LineItem(order, product, quantity);
order.getLineItems().add(li);
em.persist(li);
return li;
}
@Remove
public void destroy() {
em.close();
}
}

2.解析

First, a few words of theory...

An application-managed entity manager participates in a JTA transaction in one of two ways.

1. If the persistence context is created inside the transaction, the persistence provider will automatically synchronize

the persistence context with the transaction.
2.If the persistence context was created earlier (outside of a transaction or in a transaction that has since ended), the

persistence context can be manually synchronized with the transaction by calling joinTransaction() on the EntityManager

interface. Once synchronized, the persistence context will automatically be flushed when the transaction commits.

After reading the above definition a few questions may arise:

1.how do we know that ShoppingCartImpl participates in JTA transaction ?

  Because the class has been annotated with @Stateful (or @Stateless) annotation so the intention is to execute the class

within Java EE environment which by default uses JTA transactions. A class doesn't need such annotation, if it will be executed

in Java SE environment.

2.how do we know application-managed entity manager is used in this particular case?

Because we are using @PersistenceUnit annotation to inject EntityManagerFactory and then manually creating and destroying

EntityManager. By doing this we are telling Java EE container that we don't want our transaction to be automatically managed

(like in case of transaction-scoped entity manager or extended entity manager types).

3.why em.joinTransaction() is required in createLineItem method?

By calling em.joinTransaction() we notify the application-managed persistence context that it should synchronize itself with the

current JTA transaction. Without such call the changes to Order would not be flushed to the underlying database when the

transaction commits (at the end of createLineItem method).

NOTE: since EntityManagerFactory instances are thread-safe and EntityManager instances are not, an application must not call

em.joinTransaction() on the same entity manager in multiple concurrent transactions.

引用

http://stackoverflow.com/questions/24442335/use-of-jointransaction-in-jpa

understand EntityManager.joinTransaction()的更多相关文章

  1. Utility3:Understand Dashboard Report

    To see data in the SQL Server Utility dashboard, select the top node in the Utility Explorer tree - ...

  2. JPA中entityManager的CRUD

    private EntityManagerFactory entityManagerFactory; private EntityManager entityManager; private Enti ...

  3. 代码阅读分析工具Understand 2.0试用

    Understand 2.0是一款源代码阅读分析软件,功能强大.试用过一段时间后,感觉相当不错,确实可以大大提高代码阅读效率.由于Understand功能十分强大,本文不可能详尽地介绍它的所有功能,所 ...

  4. 【转载】Understand the serialVersionUID

    If you have ever implemented Serializable interface, you must encounter this warning message The ser ...

  5. understand一些功能

    功能 支持分析的语言 统计总的代码数据 统计单个文件的数据 分析代码复杂度 分析代码格式 文件的依赖关系 文件夹依赖关系 文件夹包含关系.代码量 understand提供了很多图表,同时它可以根据源码 ...

  6. Understand:高效代码静态分析神器详解(转)

    之前用Windows系统,一直用source insight查看代码非常方便,但是年前换到mac下面,虽说很多东西都方便了,但是却没有了静态代码分析工具,很幸运,前段时间找到一款比source ins ...

  7. Five More Hacker Tools Every CISO Should Understand

    As we mentioned in the first article, Top Five Hacker Tools Every CISO Should Understand, the role o ...

  8. Top Five Hacker Tools Every CISO Should Understand

    As the role of the CISO continues to evolve within organizations towards that of an executive level ...

  9. 如何获取EntityManager

    1.在容器内部使用,使用@PersistenceContext 来注入.@PersistenceContextprivate EntityManager em;TAG================= ...

随机推荐

  1. [转]解决Cannot change version of project facet Dynamic web module to 2.5

    我们用Eclipse创建Maven结构的web项目的时候选择了Artifact Id为maven-artchetype-webapp,由于这个catalog比较老,用的servlet还是2.3的,而一 ...

  2. Lua中的基本函数库

    assert (v [, message])功能:相当于C的断言,参数:v:当表达式v为nil或false将触发错误,message:发生错误时返回的信息,默认为"assertion fai ...

  3. 《javascript征途》学习笔记

    基础 1. 只有函数有作用域 2. 如果在<script src>的src 中设置了src特性,则script元素包含的任意代码就无效了.应该分开放到不同的script块中. 3. 外部j ...

  4. js math atan2

    在双十二活动中,视觉要求实现一个鼠标跟随运动的的效果,就像“觉”的那个效果类似 其实原理很简单,看鼠标从哪个方向进的及从哪个方向出的,然后区块里绝对定位的浮层就可以根据鼠标方向 运动; 如:在鼠标进入 ...

  5. 国际化信息-->MVC

    假设我们正在开发一个支持多国语言的Web应用程序,要求系统能够根据客户端的系统的语言类型返回对应的界面:英文的操作系统返回英文界面,而中文的操作系统则返回中文界面——这便是典型的i18n国际化问题.对 ...

  6. iOS开发之--获取验证码倒计时及闪烁问题解决方案

    大家在做验证码的时候一般都会用到倒计时,基本上大家实现的方式都差不多,先贴出一些代码来.. -(void)startTime{ __block ; //倒计时时间 dispatch_queue_t q ...

  7. Android无线测试之—UiAutomator UiScrollable API介绍五

    滑动区域校准常量设置与获取 一.校准概念 校准常量指的是:滑动操作坐标时的偏移量,用来取偏移比例 二.相关API 返回值 API 描述 double getSwipeDeadZonePercentag ...

  8. ORA-00972: 标识符过长

    若是拼接成的sql语句,请查找传递参数时字符型字段是否两边少了引号.

  9. 动态规划——最长公共子序列&&最长公共子串

      最长公共子序列(LCS)是一类典型的动归问题. 问题 给定两个序列(整数序列或者字符串)A和B,序列的子序列定义为从序列中按照索引单调增加的顺序取出若干个元素得到的新的序列,比如从序列A中取出 A ...

  10. poj_2823 线段树

    题目大意 给定一行数,共N个.有一个长度为K的窗口从左向右滑动,窗口中始终有K个数字,窗口每次滑动一个数字.求各个时刻窗口中的最大值和最小值. 题目分析 直接搜索,复杂度为O(n^2).本题可以看做是 ...