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).