Jakarta ee JavaEE6-悲观锁定-ViewScopedBean+;带UserTransaction、PreDestroy和其他问题的有状态bean
在我正在处理的应用程序中,我们需要在用户进入“编辑页面”(锁定当前编辑的DB记录)之前启动事务,并在用户单击按钮或离开页面时结束事务 为此,我使用管理事务的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
@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";
}
}
理论上看起来不错,但我们有一些问题:
@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实现。