Variable transaction isolation levels by request

Session session = getSession(dataSource, sessionFactory, Connection.TRANSACTION_SERIALIZABLE);

public Session getSession(DataSource dataSource, SessionFactory sessionFactory, int isolationLevel){

  // Get connection from current dataSource and set new isolation
  Connection connectionWithNewIsolation = dataSource.getConnection();
  connectionWithNewIsolation.setTransactionIsolation(isolationLevel);

  // Get session from current sessionFactory with the new isolation
  Session session = sessionFactory.openSession(connectionWithNewIsolation);

  // Hibernate 4.3
  //SessionFactory.openStatelessSession(Connection connection)
  // Hibernate 3.6
  //SessionFactory.openSession(Connection connection)
  //SessionFactory.openStatelessSession(Connection connection)

  return session;
}

If you're using Spring you can use something like this:

@Transactional(isolation = Isolation.SERIALIZABLE)

and it works for the JpaTransactionManager. If you are using JtaTransactionManager the request-scope transaction isolation is not propagated, as this is the default JTA behavior.

Because JTA doesn’t support transaction-scoped isolation levels, Spring offers the IsolationLevelDataSourceRouter to overcome this shortcoming when using application server JTA DataSources.

Because most DataSource implementations can only take a default transaction isolation level, we can have multiple such DataSources, each one serving connections for a specific transaction isolation level.

The logical transaction (e.g. @Transactional) isolation level setting is introspected by the IsolationLevelDataSourceRouter and the connection acquire request is therefore delegated to a specific DataSource implementation that can serve a JDBC Connection with the same transaction isolation level setting.

So, even in JTA environments, the transaction isolation router can offer a vendor-independent solution for overriding the default database isolation level on a per transaction basis.

Java EE doesn't support method-level transaction isolation configuration.

The SERIALIZABLE isolation level will protect you against non-repeatable reads and phantom reads, and even SERIALIZABLE doesn't protect you against lost updates across multiple-request logical transactions.

Optimistic locking6 scales better when using the detached entities (as of they were loaded when the logical transaction has started).