Я нахожусь в процессе миграции устаревшего приложения 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);
}
Я ожидаю, что этот код будет работать в контексте транзакции, а не выдавать ошибку, описанную выше.