jpa-2.0 - JPA 与 JTA 如何在一个事务中保留多个实体

标签 jpa-2.0 jta

我有一个对象列表。它们是 JPA“位置”实体。

List<Location> locations;

我有一个无状态 EJB,它循环遍历列表并保留每个列表。

public void createLocations() {
    List<Locations> locations = getListOfJPAManagedLocationEntities(); // I'm leaving out the details of this because it has nothing to do with the issue

    for(Location location : locations) {
        em.persist(location);
    }
}

代码运行良好。我没有任何问题。 然而,问题是:我希望这是一个全有或全无的交易。目前,每次通过 for 循环,persist() 方法都会向数据库中插入一个新行。假设我有 100 个位置对象,第 54 个对象有问题并抛出异常。将有 53 条记录插入数据库。我想要的是:在任何一个成功之前,他们必须全部成功。

我使用的是最新和最好的 Java EE6、EJB 3.x. 和 JPA 2 版本。我的 persistence.xml 使用 JTA。

<persistence-unit name="myPersistenceUnit" transaction-type="JTA">

而且我喜欢 JTA。 我不想停止使用 JTA。 90% 的时间 JTA 完全按照我的意愿行事。但在这种情况下,我似乎没有。

我对 JTA 的理解一定是不准确的,因为我一直认为 EJB 方法的开始和结束标记了 JTA 事务的边界(假设只有一个方法在运行,如我上面所示)。按照我的逻辑,在 for 循环完成并且方法返回之前,事务不会结束,然后在那个时候记录被持久化。

我正在使用 SqlServer 2008 的 JTDS 驱动程序。也许数据库不想在不立即提交的情况下插入记录。实体 id 定义如下:

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)

我已经检查过规范,在 JTA 环境中调用各种“UserTransaction”或“getTransaction()”方法是不合适的。

那我该怎么办呢? 谢谢。

最佳答案

如果您使用 JTA 和容器管理的事务,则 session EJB 方法调用的默认行为是在事务中运行(就像用 @TransactionAttribute(TransactionAttributeType.REQUIRED) 注释它一样。这意味着您的代码已经在事务中运行并将执行你期望:如果在第 54 行发生异常,所有先前插入的行都将回滚。你可以继续并通过在循环中的某个点抛出异常来测试它。请注意,如果你抛出一个由你声明的已检查异常方法,你可以指定当异常发生时容器应该做什么。你需要用 @ApplicationException (rollback=true) 注释异常类。

关于jpa-2.0 - JPA 与 JTA 如何在一个事务中保留多个实体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14990226/

相关文章:

jakarta-ee - 理解ejb3和JTA的关系

java - 如何在多线程之间共享一个事务

java - BTM 作为 Tomcat 7 中的事务管理器?

java - 嵌套事务和 EJBContext 的 setRollbackOnly()

spring - 如何访问 TomEE 的 JTA 事务管理器?

java - hibernate 延迟加载不起作用

jpa-2.0 - 如何使用 bool 条件编写 JPA 查询

hibernate - 合并具有唯一约束的实体

java - 与同一实体的一对多关系

JPA 2 "member of"语法不适用于父类(super class)成员