有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java典型的EJB3/JPA/JSF中的事务范围是什么?

假设您有一个带有EJB3/JPA和JSF堆栈的web应用程序。好吧,你可以使用不同的托管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);
  }
}

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


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

我更喜欢时间较长但数据正确的交易,而不是时间较短但数据错误的交易。我想知道像jBoss Seam这样的新框架是否以某种方式促进了这一点,或者提供了另一种设计(例如:视图模式中的开放会话)


共 (1) 个答案

  1. # 1 楼答案

    有一些选项可以控制EJB的事务行为。通常,它们有一个“Requires a transaction”设置,因此如果在事务到位的情况下调用bean,那么bean的工作将包含在已经建立的事务中,否则当bean返回时,事务将启动并完成

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

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

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

    补充说- 您已经在问题中阐明,您确实关心屏幕不同部分之间的一致性,如果使用简单的JSF技术进行编码,那么屏幕的不同部分将使用单独的事务

    在我看来,当这种不一致非常不可能或不可避免时,默认的JSF方法是合适的。例如: 1). 不太可能:查询历史数据、昨天交易总数和昨天交易列表。在一个历史无法改变的系统中,这样的独立查询将是一致的。 2). 不可避免:摘要来自一个系统,细节来自另一个系统,两个系统之间没有事务协调,我们无法确保一致性。我们只需要向用户显示这两个视图可能有点不协调

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

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