Вызовы Webservice в одной и той же транзакции JDBC вызывают тайм-ауты блокировки БД - PullRequest
2 голосов
/ 20 апреля 2011

Я использую базу данных H2, встроенную в приложение Spring-MVC.

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

  1. Начало транзакции
  2. Выполнение вызова веб-сервисов
  3. Выполнение последующих вызовов базы данных
  4. После отката (исключение) вызов веб-сервисов откатывается вручную, и Spring Transaction Manager обрабатывает вызов отката для транзакции БД.

Но я понял, что существование вызова веб-сервисов втранзакция БД вызывает блокировку всей таблицы, в результате чего другие пользователи получают ошибки (я могу произвести это в однопользовательской системе с двумя браузерами).

Я пытаюсь наметить мой лучший способ действий.

  • Должен ли я изменить уровень изоляции транзакции в Spring, повлияет ли это на блокировку БД?
  • Это просто плохая форма - иметь веб-сервис и вызов БД в одной транзакции?
  • Должен ли я включить блокировку на уровне строк в базе данных H2 из-за этого?
  • Не думаю ли я о других решениях?

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

Ответы [ 2 ]

2 голосов
/ 21 апреля 2011

Я думаю, что вы подходите разумно, и вам обязательно стоит попробовать блокировку на уровне строк, если это возможно.

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

В качестве альтернативы вам, возможно, придется просто свернуть свое собственное управление транзакциями. Пока это универсально, это не должно быть слишком много проблем. Мы сделали это в нашем проекте, где мы не используем транзакции Spring. Что-то вроде

performTransaction() {
    doWSCall();
    // no need to worry about WS call exception, because DB call won't happen
    try {
        doDbCall()
    } catch (Exception ex) {
        rollbackWSCall()
        // rethrow ex
    }
}

где все методы абстрактные.

0 голосов
/ 20 апреля 2011

Я не хотел бы, чтобы вызов веб-службы смешивался с вызовом базы данных. Ваш метод нарушает правило, которое гласит: «делай что-то хорошо».

Попросите вашу службу позвонить в другие веб-службы и DAO.

...