Весенняя сделка с Sybase - PullRequest
       12

Весенняя сделка с Sybase

0 голосов
/ 01 ноября 2009

Я использую Spring в своем веб-приложении с базой данных в качестве Sybase.

У меня есть 3 сложные хранимые процедуры, которые нужно выполнить. У процедур есть команды create table и drop table для хранения временных наборов результатов.

Таблицы создаются в пользовательском пространстве БД, а не в пространстве tempdb. Следовательно, я столкнулся с необходимостью сериализации всей операции службы из служебного компонента, которая будет иметь объекты DAO, вызывающие хранимые процессы. Означает ли простое превращение метода bean-компонента в сервис Spring Transaction решение проблем, связанных с параллелизмом в моем случае?

Еще одна вещь, которую я заметил, это то, что, пометив мой метод службы как @Transactional, заставил базу данных sybase выдать ошибку: «Невозможно выполнить команду создания таблицы в транзакции». Означает ли это, что Spring делает всю операцию с базой данных транзакцией? Мне действительно не ясно об этом, и любое объяснение будет приветствоваться. То есть, если у меня есть сохраненный процесс с именем myproc . Оператор sybase будет exec myproc . Это, скажем, выполняется DAOobject из метода сервиса, аннотируемого как @Transactional. Теперь Spring выполняет операцию базы данных как " begin trans exec myproc end tran". Мое наблюдение, кажется, предполагает это. Пожалуйста, объясните.

А также объясните, если только аннотация @Transactional решит мои проблемы с параллелизмом. Я на самом деле не хочу, чтобы 2 экземпляра моего хранимого процесса работали в базе данных одновременно.

1 Ответ

0 голосов
/ 04 января 2010

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

  • Пометка службы как @Transactional связывает ее с текущей транзакцией JTA (Java Transaction API) (или создает ее при необходимости)
  • В зависимости от того, как настроены ваши источники данных, соединения JDBC обычно также будут связаны (зачислены) в транзакцию
  • Если соединение связано с транзакцией JTA, то все, что выполняется на нем, будет происходить в транзакции базы данных.
  • В Sybase ASE вы не можете создавать (или удалять) таблицы внутри транзакции.

Таким образом, пометка вашей службы как @Transactional не позволит вам выполнить процедуру, которая содержит операторы create table.

Однако это не решит проблему, с которой вы столкнулись в любом случае. Пометка чего-либо @Transactional просто означает, что оно выполняется внутри транзакции JTA. А это значит, что он либо фиксирует, либо откатывается, но не защищает от одновременного доступа.

У вас есть несколько вариантов

  • Если вы знаете, что ваше приложение будет работать только на одной виртуальной машине, вы можете пометить код как serialized. Это гарантирует, что виртуальная машина имеет только 1 поток внутри этого кода за раз.
  • Вы можете реализовать средства управления параллелизмом внутри процедуры (например, использовать lock table), но для этого потребуется транзакция, которая не позволит вам создать таблицу внутри процедуры.
  • Или вы можете изменить дизайн приложения, чтобы не перепрыгивать через все эти обручи.

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

...