【问题标题】:EJB 3.0 transactions and synchronizationEJB 3.0 事务和同步
【发布时间】:2013-08-21 15:32:09
【问题描述】:

使用 EJB 3.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();

【问题讨论】:

    标签: transactions synchronization ejb-3.0 stateless-session-bean


    【解决方案1】:

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

    以下是文档的一些摘录,将更详细地阐明它。

    • 如果单例使用容器管理的并发,EJB 容器控制客户端访问 单身

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

    • 如果单例类上没有 @Lock 注释,则默认锁定类型 @Lock(LockType.WRITE) 将应用于所有 业务和超时方法。


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

    @Pool(value=PoolDefaults.POOL_IMPLEMENTATION_STRICTMAX,maxSize=1,timeout=5000)

    更多详情请参考here,这是特定于 JBoss 的,但可以针对其他服务器以不同方式实现。

    【讨论】:

    • 不幸的是我不能在 Jboss 5 中使用 Singleton bean。
    • @otonakav 您使用的是 EJB 3.1,是否有任何具体原因没有它。
    • 我认为 Jboss 5 正在使用 EJB 3.0,我已经编辑了这个问题。但是谢谢,因为这是 EJB 3.1 的方式
    • @otonakav 我已经为 JBoss 添加了详细信息,可以参考编辑部分,可能会有所帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-12
    • 2016-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多