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

假设您有一个带有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层时AFAIK提交所有事务;所以,如果我从表示层调用两个不同的SLSB,它将在两个不同的事务中运行(并且可能会破坏我的ACID期望吗?).

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

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

最佳答案 有一些选项可以控制EJB的事务行为.通常它们具有“需要事务”设置,因此如果使用事务调用bean,则bean的工作将包含在已建立的事务中,否则将在bean返回时启动并完成事务.

在您的代码中,在进入EJB时没有事务处理,因此当您从EJB返回时,任何事务都已解决.

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

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

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

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

你真正想要一致性的地方使用不同的方法,在一个请求中获取所有数据并保存(比如在会话或请求中)然后在两个视图中使用它 – 如果你关心这些事情,视图不应该获取自己的数据.

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

点赞