Ошибка «Невозможно установить идентификатор транзакции при подключении» - Spring DatasourceTransactionManager - PullRequest
0 голосов
/ 08 октября 2019

Я нахожусь в процессе миграции устаревшего приложения WebSphere на загрузку Spring. Это приложение интенсивно использует транзакции базы данных и, кажется, работает нормально, пока не достигнет определенного блока, помеченного как "@Transactional". Единственные ошибки, которые он выдает: «Невозможно установить идентификатор транзакции при подключении» и ошибка SQL DB2:

com.ibm.db2.jcc.am.SqlSyntaxErrorException: 
  DB2 SQL Error: 
    SQLCODE=-104, 
    SQLSTATE=42601, 
    SQLERRMC=<END-OF-STATEMENT>;
WITHIN <IDENTIFIER> INTO FROM OVER * AT YEAR YEARS , DRIVER=4.16.53

Не совсем точно, откуда исходит этот SQL, предполагая, что это может быть что-то, что Spring или драйвер используетдля связи с DB2.

Приложение может без проблем использовать транзакции другими методами.

В настоящее время мы используем самую последнюю версию драйвера JDBC DB2, доступную в моей организации, и используем SpringЗагрузиться 2.1.6. ВЫПУСК. Удаление @Transactional, кажется, «решает» проблему, однако теперь она не работает как контекст, и мы не можем рассчитывать на целостность данных, поэтому это не хорошее решение этой проблемы.

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

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

" rel="nofollow noreferrer"> Источник:"Команда Spring рекомендует аннотировать только конкретные классы (и методы конкретных классов) аннотацией @Transactional, а не аннотировать интерфейсы ..."

Добавление readOnly=true, похоже, также предотвратило возникновение ошибки, однако в этом конкретном транзакционном блоке мы выполняем вставки и обновления, так что флаг readOnly также не особенно точен.

Вот пример того, что происходит, что терпит неудачу. При отладке ошибка генерируется в классе Spring TransactionInterceptor, так что, похоже, это происходит до того, как doDatabaseStuff() будет фактически выполнен.

@Transactional
public void doDatabaseStuff(Stuff stuff){
     daoA.batchUpdate(stuff);
     daoB.batchInsert(stuff);
}

Вот пример «рабочего» кода с чтением-only:

@Transactional(readOnly = true)
public void doDatabaseStuff(Stuff stuff){
     //not readOnly operations
     daoA.batchUpdate(stuff);
     daoB.batchInsert(stuff);
}

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

...