gpt4 book ai didi

java - JPA:如何确保托管实体的属性值以事务方式写入数据库?

转载 作者:行者123 更新时间:2023-12-01 11:11:26 25 4
gpt4 key购买 nike

对我来说,这似乎是一个非常基本的问题,所以可能我要么缺乏正确的搜索词,要么我完全错过了有关托管实体如何工作的方式的一些信息,但尽管如此,我还是无法找到如何做这:以事务方式将托管实体的新属性值写入数据库,这意味着我想为实体 bean 设置一堆值,并让它们一次性全部保留,并且其他线程不会看到“脏”中间状态bean 或中断写入过程。

这是实体类:

@Entity
public class MyEntityClass
{
...
private String status;
private String value;
...
public void setStatus(String status)
{
...
public void setValue(String vlaue)
{
...
}

我在这里使用它:

import javax.ejb.Stateless;
import javax.ejb.TransactionManagement;
import javax.ejb.TransactionManagementType;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

@Stateless
@TransactionManagement(TransactionManagementType.CONTAINER)
public class MyService
{
@PersistenceContext
protected EntityManager entityManager;
...
MyEntityClass entity = entityManager.find(entityClass, id);

//Now I'd like to set some attributes in a transactional way
entity.setStatus(newStatus);

//what if the new status got persisted and another thread reads from the database now
entity.setValue(newValue);

//flushing, just to make sure that at least from here on the database is in a consistent state
entityManager.flush();
}

我需要确保没有其他线程可以看到处于“半写入”状态的实体,即新状态已经保留,但旧值仍然存在于数据库中。我尝试使用锁:

...
MyEntityClass entity = entityManager.find(entityClass, id);
entityManager.lock(entity, LockModeType.WRITE);
entity.setStatus(newStatus);
entity.SetValue(newValue);
entityManager.flush();
entityManager.lock(entity, LockTypeMode.NONE);
...

但这会抛出:

java.lang.IllegalArgumentException:实体不在持久化上下文中因为用于读取实体的事务在 entityManager.find() 完成后结束,因此持久性上下文也消失了,正如我从 this answer 了解到的那样.

另外,我读过here我无法使用使用容器管理事务的 EntityManager 手动创建事务。但是现在没有任何方法可以手动确保实体的属性保留在一起(或根本不保留)吗?或者这是否已经以某种方式自动完成?

最佳答案

由于您在 EJB 容器中运行并且您的事务由容器管理,因此 EJB bean 的每个业务方法都会在事务内调用,因此只要您的事务隔离级别未设置为 未提交读取,在方法中所做的更改将在事务提交时(即方法完成时)可见。

更新:

由于您不使用业务方法,因此您的代码似乎在没有任何事务的情况下运行。在这种情况下,每次调用 EnitytMangers 方法都会创建一个新的 PersistenceContext。这就是为什么你会遇到异常。当调用 EntityManager 的下一个方法时(创建新的 PersistenceContext 时),从 find 方法获得的实体将被分离。

关于java - JPA:如何确保托管实体的属性值以事务方式写入数据库?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32309734/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com