Контейнерно управлявана устойчивост и съхранени процедури, които създават временни таблици

Работя с някакъв наследен 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

person djb    schedule 25.07.2013    source източник
comment
Моля, добавете повече подробности: Покажете както Java кода с CMP/CMT, който извиква съхранената процедура, така и съхранената процедура, която създава временна таблица. Коя база данни?   -  person Beryllium    schedule 25.07.2013
comment
Добавих малко повече информация към въпроса   -  person djb    schedule 25.07.2013
comment
опитвали ли сте да изтеглите кода за съхранена процедура в друг метод и да го изключите от транзакцията, използвайки неподдържан тип транзакция?docs.oracle.com/javaee/5/tutorial/doc/bncij.html   -  person Raji    schedule 25.07.2013
comment
Здравей Раджи, да, опитах с NotSupported... без успех. Добавих повече информация, за да покажа какво съм направил. Може би Spring не намира анотацията по някаква причина, но все още нямам представа.   -  person djb    schedule 29.07.2013


Отговори (1)


Терминът постоянство, управлявано от контейнер в ejb 2.x означава, че EJB контейнерът обработва целия достъп до базата данни, изискван от компонента на обекта, обхватът се определя от внедряване на метод. Ако трябва да контролирате транзакция, като например извикване на commit в изпълнение на метод, ще бъдете принудени да използвате постоянството, управлявано от Bean, и методите на интерфейса UserTransaction, за да го контролирате.

За съжаление спецификациите на ejb 2.x не ви позволяват да имате смесен CMP/BMP bean обект, трябва да изберете такъв, който отговаря на вашия бизнес случай.

person groo    schedule 25.07.2013
comment
Нямам нищо против да използвам BMP, ако това е опция... но източниците на данни са конфигурирани в WAS като XA, така че получавам глобална транзакция по подразбиране. Това, от което вероятно имам нужда, е спиране на транзакция, но не работи. Тази връзка изглежда е за моя проблем: lwpro2. wordpress.com/2012/02/22/sybase-sp-set-chained-off, но вече опитах setAutoCommit(true) и setAutoCommit(false). - person djb; 29.07.2013
comment
Знаете ли начин за временно деактивиране на XA? Вероятно причината, поради която кодът ми не работи, е, че @Transactional не е в EJB? - person djb; 31.07.2013
comment
Не мисля, че можете да деактивирате XA, ако използвате конфигуриран XA драйвер. Може изобщо да не го използвате, но не мисля, че можете да го деактивирате по време на транзакция. - person groo; 31.07.2013
comment
Също така за setAutoCommit, това е валидно само ако използвате JDBC директно. Не мисля, че можете да го направите в CMP - person groo; 31.07.2013