Подтвердить что ты не робот

Уровни изоляции переменных транзакций по запросу

Я пишу небольшое приложение для аукциона, и очень важно, чтобы мои ставки записывались с уверенностью. В конце концов, последние пару секунд аукциона являются критическими моментами для покупателей, и я не могу рисковать им одновременно с торгов и иметь состояние гонки.

И, конечно же, для этой изоляции транзакций. Я могу установить уровень изоляции на сериализуемый, и мы все настроены.

Но как насчет всех остальных запросов? Если люди просматривают профили или отправляют сообщения, эти запросы не нужны нигде рядом с такой изоляцией транзакций. Для этих запросов вполне приемлемым считанный уровень изоляции.

Я устанавливаю мой уровень транзакций как часть моего спящем свойства hibernate.connection.isolation, но я бы очень хотел, чтобы быть в состоянии сделать что-то вроде session.setTransactionIsolation(newIsolation) для каждого запроса.

4b9b3361

Ответ 1

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

Ответ 2

Если вы используете Spring, вы можете использовать что-то вроде этого:

@Transactional(isolation = Isolation.SERIALIZABLE)

и он работает для JpaTransactionManager. Если вы используете JtaTransactionManager, транзакционная изоляция области запроса не распространяется, поскольку это поведение JTA по умолчанию.

Поскольку JTA не поддерживает уровни изоляции транзакций, Spring предлагает IsolationLevelDataSourceRouter для преодоления этого недостатка при использовании сервера приложений JTA DataSources.

Поскольку большинство реализаций DataSource могут использовать только уровень изоляции транзакций по умолчанию, мы можем иметь несколько таких источников данных, каждый из которых обслуживает соединения для определенного уровня изоляции транзакции.

Значение уровня изоляции логической транзакции (например, @Transactional) проверяется IsolationLevelDataSourceRouter, и поэтому запрос на получение соединения делегируется конкретная реализация DataSource, которая может обслуживать соединение JDBC с одинаковым уровнем изоляции транзакций.

Таким образом, даже в средах JTA маршрутизатор изоляции транзакций может предложить независимое от поставщика решение для переопределения уровня изоляции базы данных по умолчанию для каждой транзакции.

Java EE не поддерживает конфигурацию изоляции транзакций на уровне метода.

SERIALIZABLE уровень изоляции защитит вас от неповторяющихся чтений и phantom, и даже SERIALIZABLE не защитит вас против потерянных обновлений в логических транзакциях с несколькими запросами.

Оптимистическая блокировка лучше масштабируется при использовании отдельных объектов (поскольку они были загружены при запуске логической транзакции).

Ответ 3

В этом случае я буду использовать Оптимистичный замок в ваших объектах ставок... состояние гонки все равно произойдет, но оно будет обнаружено когда транзакция пытается зафиксировать изменения в ваших объектах домена (бросая исключение, если прочитанная версия была обновлена ​​другим потоком).

Таким образом, любое изменение на любом объекте ставки будет почти сериализуемым (я говорю "почти", потому что для того, чтобы быть сериализуемым, неудачные транзакции должны быть уловлены и каким-то образом пройдены).

Ответ 4

Если установка уровня изоляции для каждой транзакции завершается с ошибкой, вы всегда можете сериализовать определенную операцию вручную в своем коде (синхронизированный, семафоры и т.д.). однако имейте в виду, что он не масштабируется (один jvm, одна операция, легко случайно исключается из других частей кода)