【问题标题】:declare a transaction in ejb 3.0在 ejb 3.0 中声明一个事务
【发布时间】:2011-04-12 18:33:45
【问题描述】:

如何强制 EJB 在每个命令后不刷新所有内容,我想做一个事务。我读过这是以某种方式以声明方式完成的。但具体如何?

@Stateless
public class SomeBean{
@PersistenceContext
EntityManager em;
public void doSomeStuffAndThenFlushToTheDb(){
    em.persist(entity);
    // it's flushed by now, I don't want that
    em.persist(somethingElse);
    // now I want to flush both
    em.flush();
  }
}

【问题讨论】:

  • 哪个数据库?如果您的数据库不支持事务(例如 mysql 中的 myisam),可能会出现奇怪的结果
  • 如果要回滚当前事务,使用“@Resource SessionContext context”将SessionContext注入bean并调用context.setRollbackOnly()回滚。

标签: java jpa jakarta-ee persistence ejb-3.0


【解决方案1】:

您好,如何强制 EJB 在每个命令后不刷新所有内容,我想做一个事务。

首先,你不应该在“每条命令”之后得到flush,我真的很惊讶你在persist之后得到flush。您是否显示所有代码?其次,默认情况下 EJB 方法是事务处理的。但是事务和flush 并不真正相关(唯一的链接是flush 将在commit 之前完成)。总之……

如果您想控制flush() 调用的执行方式,您可以使用EntityManager#setFlushMode() 更改默认刷新模式。刷新模式如下:

  • COMMIT - 刷新仅在事务提交时发生,或者在调用 flush() 时发生。
  • AUTO -(默认)在任何查询执行之前进行刷新。

所以这样的东西应该可以工作:

@Stateless
public class SomeBean {
    ...
    public void doSomeStuffAndThenFlushToTheDb(){
        em.setFlushMode(COMMIT);
        em.persist(entity);
        em.persist(somethingElse);
        em.flush(); // Causes flush
    }
    ...
}

但正如我所说,我对你的例子感到惊讶。你描述的行为不是我所期望的。

【讨论】:

  • em.setFlushMode(FlushModeType.COMMIT);em.persist(match); em.clear(); em.flush(); ,我希望在这个简洁的例子中没有任何东西保存在数据库中,但事实恰恰相反,为什么?当我通过em.clear()清除所有内容时?
  • @coubeatczech 这是一个完全不同的问题,不容易在评论框中讨论。请打开另一个问题并提及您的 JPA 提供商(但无论如何您的用例真的很奇怪)。
【解决方案2】:

首先,“刷新”意味着只将它存储在二级缓存(数据库驱动程序)。它不直接存储在数据库中。自从事务完成并发送提交后,实体就保存在缓存中。 “清除”意味着分离实体。这并不意味着清除数据库。所以之后你不能再持久化这个实体了。但是持久化仍然会在事务结束时完成。

【讨论】:

  • 实际上 flush() 的文档说:“将持久性上下文同步到底层数据库”。但是,flush 不会导致提交
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多