【问题标题】:What is the transaction scope in a typical EJB3/JPA/JSF?典型的 EJB3/JPA/JSF 中的事务范围是什么?
【发布时间】:2011-12-23 15:36:19
【问题描述】:

假设您有一个带有 EJB3/JPA 和 JSF 堆栈的 Web 应用程序。 AFAIK 您可以使用不同的托管 bean 来设计您的屏幕,例如,假设一个 HeaderBean 和一个 ListingBean。由于 EJB3 AFAIK 中没有 OSIF 模式,因此在以下伪代码中执行了多少不同的事务:

@ManagedBean
class HeaderBean {
  @PreConstruct
  load(){
    // enters transaction boundary, probably will create a new tx
    headerInfo = ejb.loadFromDb();
  }
}

@ManagedBean
class ListingBean{
  @PreConstruct()
  list(){
    // enters transaction boundary, probably will NOT join the headerBean tx
    List<Data> listing = eao.loadFromDb(0, 20);
  }
}

当您离开 EJB 层时,所有事务都已提交;因此,如果我从表示层调用两个不同的 SLSB,它将在两个不同的事务中运行(并且可能会打破我的 ACID 期望,对吧?)。


澄清:我知道 EJB3 事务行为,例如 required, never, requires_new 等。我的问题更多是关于View-First(例如 JSF)如何促进这种设计,其中屏幕数据可能跨越多个事务,因此可能不准确。

我更喜欢较长的交易但数据正确,而不是较短的交易但数据不正确。我想知道诸如 jBoss Seam 之类的新框架是否会以某种方式促进这一点或提供替代设计(例如:Open-Session-In-View 模式)。

【问题讨论】:

  • CMT 仅在 EJB 上可用。 loadFromDb 方法的名字看起来甚至不需要事务。

标签: java jsf architecture transactions ejb-3.0


【解决方案1】:

有一些选项可以控制 EJB 的事务行为。通常他们有一个“需要一个事务”设置,这样如果一个 bean 被调用时有一个事务,那么 bean 的工作就包含在已经建立的事务中,否则一个事务将在 bean 返回时启动并完成。

在您的代码中,在进入 EJB 时没有任何事务到位,所以正如您所说,在从 EJB 返回时,任何事务都已解决。

虽然这似乎存在问题,因为您可能会获得不一致的数据视图,但我认为这种行为是可取的。我们希望在事务中花费的时间很短 - 否则数据库锁会被长时间持有,因此并发性会受到影响。

EJB 层应该被视为提供原子服务并相应地设计和使用。我不知道我是否正确阅读了您的代码,但是为 Header 和 Body 设置单独的访问方法可能不是最好的设计。如果您需要标头和正文之间的一致性,则在一次调用中获取所有数据可能更可取,并且实际上在单个数据库交互中更有效。

---添加--- 您已在问题中澄清说,您确实担心屏幕不同部分之间的一致性,如果使用简单的 JSF 技术进行编码,则会使用单独的事务。

在我看来,当这种不一致极不可能或不可避免时,默认的 JSF 方法是合适的。例子: 1)。不太可能:查询历史数据、昨天的交易总数和昨天的交易列表。在历史无法更改的系统中,此类单独的查询将是一致的。 2)。不可避免:摘要来自一个系统,细节来自不同系统,两个系统之间没有事务协调,我们无法保证一致性。我们只需要向用户表明这两个视图可能略有不同步。

如果您确实希望保持一致性,请使用不同的方法,在单个请求中获取所有数据并保存(例如在会话或请求中),然后在两个视图中使用它 - 如果您关心,视图不应获取自己的数据关于这些事情。

我认为您会发现尝试使用事务来保持事物的一致性会增加相当大的复杂性并影响吞吐量。跨视图协调事务的问题在于没有简单的“所有者”,如果您重构页面,则需要更改逻辑

【讨论】:

  • 请查看我的说明。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-18
  • 2015-10-31
  • 1970-01-01
  • 1970-01-01
  • 2012-04-11
相关资源
最近更新 更多