Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/css/34.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Jakarta ee JavaEE6-悲观锁定-ViewScopedBean+;带UserTransaction、PreDestroy和其他问题的有状态bean_Jakarta Ee_Transactions_Java Ee 6_Stateful Session Bean_Pessimistic Locking - Fatal编程技术网

Jakarta ee JavaEE6-悲观锁定-ViewScopedBean+;带UserTransaction、PreDestroy和其他问题的有状态bean

Jakarta ee JavaEE6-悲观锁定-ViewScopedBean+;带UserTransaction、PreDestroy和其他问题的有状态bean,jakarta-ee,transactions,java-ee-6,stateful-session-bean,pessimistic-locking,Jakarta Ee,Transactions,Java Ee 6,Stateful Session Bean,Pessimistic Locking,在我正在处理的应用程序中,我们需要在用户进入“编辑页面”(锁定当前编辑的DB记录)之前启动事务,并在用户单击按钮或离开页面时结束事务 为此,我使用管理事务的@Statefulejbbean和在“编辑页面”上使用的CDI@ViewScopedbean 当然,用户可以在编辑页面上执行许多操作,这些操作应该在同一事务中调用。 下面是示例代码: @Stateful @LocalBean @TransactionManagement(TransactionManagementType.BEAN) publ

在我正在处理的应用程序中,我们需要在用户进入“编辑页面”(锁定当前编辑的DB记录)之前启动事务,并在用户单击按钮或离开页面时结束事务

为此,我使用管理事务的
@Stateful
ejbbean和在“编辑页面”上使用的CDI
@ViewScoped
bean

当然,用户可以在编辑页面上执行许多操作,这些操作应该在同一事务中调用。 下面是示例代码:

@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";
  }
}
理论上看起来不错,但我们有一些问题:

  • 我们能否确保在同一事务中调用所有操作
  • 若用户通过键入地址栏或http会话超时来关闭选项卡/浏览器/转到另一个URL,该怎么办。我们如何检测它并回滚事务?起初,我们尝试了
    @PreDestroy
    ,但它似乎从未被调用过 我们使用JavaEE6技术:JSF、EJB。在Glassfish 3.1.2 Web配置文件上部署。我们用MyBatis代替JPA。
    谢谢你的帮助,我觉得这是一个非常糟糕的方法。您锁定表并等待,希望用户做些什么。可能需要几分钟。所有其他用户将不得不等待这一次-在大多数应用程序中,这是不可接受的。您不应该跨越多个http请求之间的事务


    但是,如果您坚持,回滚不能依赖于某些外部事件。只需设置事务超时

    在我们的情况下,这是理想的行为。用户编辑甚至可以持续1小时,我们必须确保DB在此期间没有更改,这样他就可以安全地保存他的工作。很少有应用程序使用相同的数据库,我们必须防止其他应用程序编辑相同的数据。我们并没有锁定整个表,只有单行.CDI没有视图范围的Bean。您可能正在使用JSF管理的Bean。希望您不要在这两种bean之间混合注释,因为这会破坏bean的作用域。我使用seam faces 3.0,它具有CDI ViewScope实现。