Transactions EJB3.0事务和同步

Transactions EJB3.0事务和同步,transactions,synchronization,ejb-3.0,stateless-session-bean,Transactions,Synchronization,Ejb 3.0,Stateless Session Bean,使用EJB3.0,两个线程将尝试运行此代码(在无状态会话bean中)。两个线程都能够通过if语句并打印出该语句 userTransaction.begin(); //userTransaction is of class UserTransaction myEntity = entityManager.find(MyEntity.class, id); //entityManager is of class EntityManager if (myEntity.getStatus() != "D

使用EJB3.0,两个线程将尝试运行此代码(在无状态会话bean中)。两个线程都能够通过if语句并打印出该语句

userTransaction.begin(); //userTransaction is of class UserTransaction
myEntity = entityManager.find(MyEntity.class, id); //entityManager is of class EntityManager
if (myEntity.getStatus() != "DONE") {
    myEntity.setStatus("DONE");
    entityManager.merge(myEntity);
    System.out.println("Only one thread should be running this");
}
userTransaction.commit();
我已尝试将事务隔离级别设置为可序列化,但未成功:

org.hibernate.Session session = (org.hibernate.Session) entityManager.getDelegate();
session.connection().setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE);
也许我用错了方法

更新

无法使用单例会话bean,因为Jboss 5不支持它们。现在,我正在尝试以下代码,但在其他时间遇到了死锁问题:

connection.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE);
connection.setAutoCommit(false);

//selectStatement and updateStatement are of type PreparedStatement
selectStatement = connection.prepareStatement("SELECT STATUS FROM MYTABLE WHERE STATUS != 'DONE' AND ID=?");
selectStatement.setInt(1, id);

updateStatement = connection.prepareStatement("UPDATE MYTABLE SET STATUS = 'DONE' WHERE ID=?");
updateStatement.setInt(1, id);

resultSet = selectStatement.executeQuery();
if (resultSet.next()) {
   updateStatement.executeUpdate();
}
connection.commit();

您可以将相关代码或整个方法转移到单例会话bean中,并应用适当的锁定策略

以下是文件中的一些摘录,将对其进行更详细的说明

  • 如果单例使用容器管理的并发,EJB容器将控制客户端对 独生子女

  • 如果单例会话bean应该锁定到其他客户端,则使用@Lock(LockType.WRITE)注释业务或超时方法 当客户端调用该方法时。通常情况下 @在客户端修改时使用Lock(LockType.WRITE)注释 独生子女的状态

  • 如果singleton类上不存在@Lock注释,则默认的锁类型@Lock(LockType.WRITE)将应用于所有 业务和超时方法


编辑:作为一种解决方法,您可以使用池大小为1的无状态会话bean。使用bean上的
@Pool
注释或通过xml配置指定它

@Pool(value=PoolDefaults.Pool\u IMPLEMENTATION\u STRICTMAX,maxSize=1,timeout=5000)


有关更多详细信息,请参阅,这是JBoss特有的,但可以在其他服务器上以不同的方式实现。

不幸的是,我不能在JBoss 5中使用单例bean。@otonakav您使用的是EJB 3.1,没有它有什么具体的原因。我想JBoss 5使用的是EJB 3.0,我已经编辑了这个问题。但是谢谢,因为这是EJB3的发展方向。1@otonakav我已经为JBoss添加了详细信息,可以参考编辑部分,可能会有所帮助。