Работя с някакъв наследен JDBC код и го конфигурирам да използва Container Managed Persistence и досега работи добре с транзакции, управлявани за мен, освен че не успява при извиквания на съхранена процедура.
Някои от съхранените процедури създават временни таблици, които изискват ангажимент по средата на транзакцията. Така че получавам изключение, което се оплаква, че не мога да извикам commit, ако използвам постоянство, управлявано от контейнер.
Някой знае ли начин за това?
Повече информация:
Ако добавя commit() в края на моите заявки, получавам:
DSRA9350E: Операция Connection.commit не е разрешена по време на глобална транзакция.
Така че предположих, че драйверът на Sybase JDBC 4 XA управлява транзакции вместо мен. Той се връща назад, ако хвърля изключение в моя код.
public Connection getConnection() throws SQLException {
if ( connection == null ) {
this.connection = dataSource.getConnection();
this.connection.setAutoCommit(!useTransaction);
this.connection.setTransactionIsolation(transactionIsolationLevel);
}
logger.info("Connection [ "+ connection.toString() +" ]");
return connection;
}
Частта, в която получавам връзката, обикновено има autocommit като „false“, докато за съхранените процедури има autocommit като „true“. Но така или иначе, съхранените процедури с временни таблици получават:
java.sql.SQLException: командата SELECT INTO не е разрешена в транзакция с множество изрази.
Това е малко объркващо. Източниците на данни се настройват от контейнера и аз просто ги получавам от контекста, използвайки тагове resource-ref. Те са XA източници на данни, така че предоставят глобална транзакция. Опитвам се да го деактивирам с Spring:
<context:component-scan base-package="package.path.to.class.with.method" />
<tx:annotation-driven />
<bean id="transactionManager" class="org.springframework.transaction.jta.WebSphereUowTransactionManager" />
чрез предоставяне на @Component на класа и @Transactional на метода
@Transactional(propagation=Propagation.NOT_SUPPORTED)
public ResultSet executeProcedure(String sql, String[] parameterTypes,
String[] parameterValues) throws SEEException {
SqlParameters parameters = this.convertParameters(parameterTypes, parameterValues);
return super.executeProdedure(sql, parameters);
}
Но все още получавам грешката.
Съхраненият процес изглежда малко по този начин (procxmode е UNCHAINED). Съхранената дефиниция на процедурата сама по себе си е транзакция, така че предполагам, че не трябва да влизам в активна транзакция. Но няма да мога да редактирам самата съхранена процедура. Произвежда се от години:
define sp_example
begin
create table #temp {}
begin
insert into #temp {}
end
begin
select from #temp {}
end
end