Using EJB 3.0, two threads will try to run this code (that is inside a stateless session bean). Both threads are able to pass through the if statement and print out the statement.
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();
I've tried setting the transaction isolation level to serializable with no success:
org.hibernate.Session session = (org.hibernate.Session) entityManager.getDelegate();
session.connection().setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE);
Maybe I'm using the wrong approach.
UPDATE
Cannot use Singleton session beans because Jboss 5 does't support them. Right now I'm trying the following code with the problem that I run into deadlock some other time:
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();