Java EE 6 - Pessimistic Locking - ViewScoped bean + Stateful bean with UserTransaction, PreDestroy and other problems

回眸只為那壹抹淺笑 提交于 2019-12-11 14:11:44

问题


In application I'm working on we need to start transaction before user enters 'edit page' (to lock DB records currently edited) and end it when he clicks the button or left the page.

For this purpose I use @Stateful EJB bean which manages the transaction and CDI @ViewScoped bean which is used on the 'edit page'.

Of course user can take many actions on edit page, which are supposed to be invoked within the same transaction. Here's sample code:

@Stateful
@LocalBean
@TransactionManagement(TransactionManagementType.BEAN)
public class TransactionService {

  @Resource
  private UserTransaction utx;

  @PostConstruct
  private void postConstruct() {
    System.out.println(this + " postConstruct");
  }

  @PreDestroy
  private void preDestroy() {
    System.out.println(this + " preDestroy");
    utx.rollback();
  }

  public void start() {
    utx.begin();
    //lock db records with select ... for update
  }

  @Remove
  public void commit() {
    utx.commit();
  }

  @Remove
  public void rollback() {
    utx.rollback();
  }
}

@Named
@ViewScoped
public class TestBean implements Serializable {

  @Inject
  private TransactionService ts;
  @Inject
  private SqlService sql; //stateless session bean

  @PostConstruct
  private void postConstruct() {
    System.out.println(this + " postConstruct");
    ts.start();
  }

  @PreDestroy
  private void preDestroy() {
    System.out.println(this + " preDestroy");
    ts.rollback();
  }

  public void methodA() {
    //do some db operation
    sql.insert();
  }

  public void methodB() {
    //do some db operation
    sql.update();
  }

  public String save() {
    ts.commit();
    return "otherView";
  }

  public String cancel() {
    ts.rollback();
    return "otherView";
  }
}

In theory it looks fine, but we have some questions:

  1. Can we be sure that all operations are invoked in the same transaction?
  2. What if user closes tab/browser/goes to another URL by typing in address bar or http session times out. How can we detect it and rollback the transaction? At first we tried with @PreDestroy but it looks like it's never called!

We use Java EE 6 technologies: JSF, EJB. Deploy on Glassfish 3.1.2 Web Profile. We use MyBatis instead JPA. Thanks for help


回答1:


IMHO it's very bad approach. you lock your table and wait hoping that user does something. it may take minutes. all other users will have to wait for this one - in most applications it's unacceptable. you shouldn't span transaction between between multiple http requests.

however, if you insist, rollback must not depends on some external events. simply set a transaction timeout



来源:https://stackoverflow.com/questions/12655365/java-ee-6-pessimistic-locking-viewscoped-bean-stateful-bean-with-usertrans

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!