繁体   English   中英

按请求可变事务隔离级别

[英]Variable transaction isolation levels by request

我正在编写一个小拍卖应用程序,并且确定地记录我的出价非常重要。 毕竟,拍卖的最后几秒对买家来说是关键时刻,我不能冒险让他们同时出价和竞争。

当然,这就是事务隔离的用途。 我可以将我的隔离级别设置为可序列化,我们都设置好了。

但是所有其他请求呢? 如果人们正在查看个人资料或发送消息,则这些请求不需要接近这种事务隔离的任何地方。 对于这些请求,读提交隔离级别是完全可以接受的。

我正在将我的事务级别设置为我的休眠属性hibernate.connection.isolation ,但我真的希望能够为每个请求执行session.setTransactionIsolation(newIsolation)

如果您使用的是 Spring,则可以使用以下内容:

@Transactional(isolation = Isolation.SERIALIZABLE)

它适用于 JpaTransactionManager。 如果您使用 JtaTransactionManager,则不会传播请求范围事务隔离,因为这是默认的 JTA 行为。

因为 JTA 不支持事务范围的隔离级别,Spring 提供了IsolationLevelDataSourceRouter来克服使用应用程序服务器 JTA 数据源时的这个缺点。

因为大多数数据源实现只能采用默认的事务隔离级别,所以我们可以有多个这样的数据源,每个数据源服务于特定事务隔离级别的连接。

逻辑事务(例如@Transactional)隔离级别设置由IsolationLevelDataSourceRouter内省,因此将连接获取请求委托给特定的 DataSource 实现,该实现可以为具有相同事务隔离级别设置的 JDBC 连接提供服务。

因此,即使在 JTA 环境中,事务隔离路由器也可以提供独立于供应商的解决方案,用于在每个事务的基础上覆盖默认数据库隔离级别。

Java EE 不支持方法级事务隔离配置。

SERIALIZABLE 隔离级别将保护您免受不可重复读取和幻读的影响,甚至 SERIALIZABLE 也不能保护您免受跨多个请求逻辑事务丢失更新的影响。

使用分离的实体时,乐观锁定 6 的扩展性更好(在逻辑事务启动时加载它们)。

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;
}

对于这种情况,我将在您的出价对象中使用乐观锁......竞争条件仍然会发生,但是当事务尝试提交您的域对象的更改时会被检测到(如果读取的版本已更新,则会引发异常通过另一个线程)。

因此,对任何出价对象的任何更改都几乎是可序列化的(我说“几乎”是因为为了可序列化,需要捕获失败的交易并以某种方式重试)。

如果为每个事务设置隔离级别失败,您始终可以在代码中手动序列化特定操作(同步、信号量等)。 但是请记住它不可扩展(单个 jvm,单个操作,容易被其他部分的代码意外绕过)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM