在我们的 J2EE 应用程序中,我们使用 EJB-3 有状态 bean 来允许前端代码创建、修改和保存持久实体(通过 JPA-2 管理)。
它看起来像这样:
@LocalBean
@Stateful
@TransactionAttribute(TransactionAttributeType.NEVER)
public class MyEntityController implements Serializable
{
@PersistenceContext(type = PersistenceContextType.EXTENDED)
private EntityManager em;
private MyEntity current;
public void create()
{
this.current = new MyEntity();
em.persist(this.current);
}
public void load(Long id)
{
this.current = em.find(MyEntity.class, id);
}
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public void save()
{
em.flush();
}
}
非常重要,为了避免过早提交,只有save()
方法在事务内,所以如果我们调用create()
,我们在数据库中不插入任何内容。
奇怪的是,在save()
方法,我们必须调用em.flush()
才能真正打到数据库。其实我尝试了一下发现我们也可以调用em.isOpen()
or em.getFlushMode()
,以及任何“与em相关”的东西。
我不明白这一点。作为save()
在一个事务中,我认为在方法结束时,事务将被提交,因此持久实体管理器会自动刷新。为什么我必须手动冲洗它?
谢谢,
泽维尔
直接针对金属,不会有javax.transaction.Synchronization
为相关 EntityManager 注册的对象,直到您实际use it in一笔交易。
我们在应用程序服务器领域将创建这些对象之一来执行以下操作flush()
并将其注册到javax.transaction.TransactionSynchronizationRegistry
or javax.transaction.Transaction
。除非有活跃的交易,否则无法完成此操作。
这就是它的长处和短处。
是的,应用程序服务器可以很好地保留它提供给有状态 bean 的资源列表,并在有状态 bean 可能启动或参与的每个事务中自动注册它们。这样做的缺点是您完全失去了决定哪些事情该去的能力其中交易。也许您有 2 或 3 个不同的事务要在不同的持久性单元上运行,并且正在为一个非常特定的事务在扩展持久性上下文中聚合工作。这实际上是一个设计问题,应用程序服务器应该将此类决定留给应用程序本身。
您在交易中使用它,我们会将其注册到交易中。这就是基本合同。
旁注,取决于底层 EntityManager 的处理方式,any对 EntityManager 的持久调用may足以在事务结束时导致完全刷新。当然,flush()
是最直接、最明确的,但persist()
甚至是一个find()
可能会做到。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)