2011-12-23 22 views
4

假设您有一个具有EJB3/JPA和JSF堆栈的Web应用程序。 AFAIK你可以使用不同的托管bean设计你的屏幕,例如,假设一个HeaderBean和一个ListingBean。由于有在EJB3据我所知没有OSIF模式,不同的交易有多少在下面的伪代码执行:典型的EJB3/JPA/JSF中的事务范围是什么?

@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层的所有交易承诺;所以如果我从表示层调用两个不同的SLSBs,它将运行在两个不同的事务中(并且可能会破坏我的期望吧?)。


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

我更喜欢较长的交易,但数据比短交易更正确,但数据不正确。我在想,如果像jBoss Seam这样的新框架以某种方式促进了这一点,或者提供了另一种设计(例如:Open-Session-In-View模式)。

+1

CMT仅在EJB上可用。 'loadFromDb'方法的名称甚至不像它需要事务。 – 2011-12-23 15:58:35

回答

2

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

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

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

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

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

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

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

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

+0

请检查我的说明。 – 2011-12-23 17:37:23

+0

我已经扩展了我的答案 – djna 2011-12-23 23:00:05