1.0          其他语言
 
 

3.3.4 每个网络请求一个事务 transaction per request

 
 

在 EJB 中,事务定义在业务函数级别。这并没有什么错,但是想保证程序员在一个请求中不调用超过一个 EJB 函数,并不容易。大多数情况下,程序员都会写出这样的代码。这会导致事务以意料之外的方式运行。

VelocityWeb 采用了另外一种方式,那就是每个网络请求一个事务 TRANSACTION_PER_REQUEST。通过在请求分发器上定义事务级别,整个框架可以在需要事务的时候启动事务。

在这种方式下,不管一个请求中,调用了多少个业务函数,VelocityWeb 都会保证它们运行在一个事务里。

程序员不需要关注事务管理,VelocityWeb 会处理好这部分工作。

将事务级别定义在请求上,而不是业务函数上,是否恰当?

答案是"YES"。

大多数情况下,整个项目/产品中,只有两种事务级别:查询(没有事务,TRANSACTION_NONE), 更新(大多数使用 TRANSACTION_READ_COMMITTED)。

对每一个请求,比如,增加用户,修改用户,删除用户,查找用户,查看用户,即使是业务方面的人都可以告诉我们,它是一个查询请求还是一个更新请求。这直接导致了一个新的设计模式:TRANSACTION_PER_REQUEST。我们可以这么说,事务级别,是请求分发器的一个属性。

可以在分发器的构造函数中调用 setTransactionIsolation(xx)。或者,直接写 QueryDispatcher 或 UpdateDispatcher 的子类。

public class StoreMainDispatcher extends QueryDispatcher {
    Log log = LogFactory.getLog(this.getClass());

    public StoreMainDispatcher() {
        this.setHtmlTemplateFileName("system/store_main.htm");
        this.setPageTitle("Default Store Home");
    }

    public String getUrlId() {
        return "store_main";
    }

    public boolean process(HttpServletRequest request, WebAppContext context, Controller controller) throws Exception {
        log.debug("process");
        context.put("view_category_url", DispatcherTreeManager.getUrl(ViewCategoryDispatcher.class));

        return true;
    }

}