典型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);
  }
}
当你离开EJB层时,所有事务都被提交;因此,如果我从表示层调用两个不同的SLSBs,它将在两个不同的事务中运行(并且可能打破我的ACID期望,对吗?)

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

我更喜欢长事务但数据正确,而不是短事务但数据不正确。我想知道新的框架,如jBoss Seam是否在某种程度上促进了这一点,或者提供了另一种设计(例如:Open-Session-In-View模式)。

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

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

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

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

——补充道您已经在您的问题中澄清了,您确实关心屏幕的不同部分之间的一致性,如果使用简单的JSF技术进行编码,将使用单独的事务。

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

如果你真的想要一致性,请使用不同的方法,在单个请求中获取所有数据并保存它(例如在session或request中),然后在两个视图中使用它-如果你关心这些事情,视图不应该获取自己的数据。

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

最新更新