cor*_*iKa 20 java database concurrency hibernate transactions
我正在写一个小小的拍卖应用程序,我的出价肯定会被记录下来非常重要.毕竟,拍卖的最后几秒是买家的关键时刻,我不能冒险同时竞标和竞争条件.
当然,这就是事务隔离的目的.我可以将我的隔离级别设置为可序列化,我们都已设置好.
但是所有其他要求呢?如果人们正在查看配置文件或发送消息,则这些请求不需要接近那种事务隔离.读提交的隔离级别对于这些请求是完全可接受的.
我将我的事务级别设置为我的hibernate属性的一部分hibernate.connection.isolation,但我真的希望能够session.setTransactionIsolation(newIsolation)按照请求执行某些操作.
如果您使用的是Spring,可以使用以下内容:
@Transactional(isolation = Isolation.SERIALIZABLE)
Run Code Online (Sandbox Code Playgroud)
和它的工作原理为JpaTransactionManager接口.如果您使用的是JtaTransactionManager,则不会传播请求范围事务隔离,因为这是默认的JTA行为.
由于JTA不支持事务范围的隔离级别,因此Spring提供了IsolationLevelDataSourceRouter来克服使用应用程序服务器JTA DataSource时的这一缺点.
因为大多数DataSource实现只能采用默认的事务隔离级别,所以我们可以拥有多个这样的DataSource,每个DataSource为特定的事务隔离级别提供连接.
IsolationLevelDataSourceRouter会对逻辑事务(例如@Transactional)隔离级别设置进行内省,因此将连接获取请求委托给可以为具有相同事务隔离级别设置的JDBC连接提供服务的特定DataSource实现.
因此,即使在JTA环境中,事务隔离路由器也可以提供独立于供应商的解决方案,以便在每个事务的基础上覆盖默认数据库隔离级别.
Java EE不支持方法级事务隔离配置.
在SERIALIZABLE隔离级别将保护您免受不可重复的读取和幻象读取,甚至是序列化并不能保护你对跨多个请求逻辑事务丢失更新.
当使用分离的实体时(从逻辑事务开始时加载它们),乐观锁定会更好地扩展.
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;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2525 次 |
| 最近记录: |