Я столкнулся со следующим, и я хотел бы посмотреть, видел ли кто-нибудь это раньше или мог бы дать мне объяснение.
У меня есть хранимая процедура, которую нужно запустить в одной транзакции. В частности, хранимая процедура содержит следующие строки кода:
set @v_nested_transactions = @@trancount;
if @v_nested_transactions = 0
begin
raiserror('Error: must be within a single transaction', 11, 1);
end
else if @v_nested_transactions >= 2
begin
raiserror('Error: must not be used within nested transactions', 11, 1);
end;
Я использую Spring и mybatis для вызова хранимой процедуры. Я использую фасадный слой, который вызывает сервис -> репозиторий -> DAO. Звонки производятся следующим образом:
Слой фасада
@Override
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void callProcedure(final long id) {
callProcedureService.callProcedure(id);
}
Уровень обслуживания:
@Override
public void callProcedure(final long id) {
CallProcedureRepository.callProcedure(id);
}
Репозиторий:
public void callProcedure(final long id) {
callProcedureDao.callProcedure(id);
}
Слой DAO:
@Override
@Transactional(propagation = Propagation.MANDATORY)
public void callProcedure(final long id) {
final Map<String, Object> parameters = new HashMap<>();
parameters.put("id", id);
this.sqlSession.update("callProcedure", parameters);
}
Хранимая процедура вызывается из карты SQL с помощью mybatis-spring. Класс, вызывающий обновление, - это SQLSessionTemplate.class. Карта sql выглядит так:
<update id = "callProcedure" statementType = "CALLABLE" parameterType = "map">
{CALL package.callProcedure(
#{id, mode=IN, jdbcType=NUMERIC})}
</update>
Наконец, я использую следующее в файле persistence-context.xml проекта Spring.
<tx:annotation-driven transaction-manager = "transactionManager" mode = "aspectj"/>
Хранимая процедура работает по назначению. Я проверил это, удалив проверку @@ trancount.
Моя проблема в том, что хранимая процедура всегда выдает ошибку «Ошибка: должно быть в рамках одной транзакции». После выполнения нескольких тестов кажется, что spring правильно создает новую транзакцию для хранимой процедуры, и если что-то пойдет не так, транзакция откатится Однако транзакция не отображается в диспетчере транзакций на сервере MS SQL; это означает, что @@ trancount всегда возвращает 0.
Кто-нибудь сталкивался с этой проблемой раньше? Есть ли обходной путь, который я мог бы использовать?
Спасибо
Я обновил сообщение, добавив больше информации. Как видите, я не делаю ничего особенного в своем коде. Это довольно простой вызов хранимой процедуры. Если вам потребуется дополнительная информация, дайте мне знать.
Как называется метод
callProcedure
? Как выглядит ваша услуга? Покажи свою конфигурацию ...