1.0          Other languages

3.3.4 Transaction per request


In EJB, transaction is defined at business function level. There is nothing wrong on this, but it's not easy to make sure programmers will not call more than one EJB functions in one request. In most normal case, programmers will write code to call more one one EJB functions one by one in one request. This will cause the transaction runs in an unexpected way.

VelocityWeb make it in another way, that is TRANSACTION_PER_REQUEST. By define the transaction level at each request dispatcher, the framework can start transaction when need.

In this way, no matter how many business functions been called in one request, VelocityWeb can make sure all of them run in single transaction.

Programmers don't need to pay much attention to transation management, VelocityWeb will do all of this work.

Is it suitability to define transaction level on request level instead of business function?

The answer is "YES".

In most case, there are only two transaction level in projects/applications: query(no transaction,TRANSACTION_NONE), update(most of us use TRANSACTION_READ_COMMITTED).

For each request, for example, add user, modify user, delete user, search user, view user, even business customers can tell us whether it's a query request or update request. This directly cause to a new design pattern: TRANSACTION_PER_REQUEST. We can say that, transaction level is a property of request dispatcher.

We can call setTransactionIsolation(xx) in constructor of each request dispatcher class. Or, just write a sub-class of QueryDispatcher or UpdateDispatcher:

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

    public StoreMainDispatcher() {
        this.setPageTitle("Default Store Home");

    public String getUrlId() {
        return "store_main";

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

        return true;