Saudações,
Estou a alguns dias me batendo com alguns problemas com a parte de transações com o banco de dados. Utilizo o Spring, Maven e o Glassfish como local container. Na execução de um dos meus serviços preciso inserir/alterar registros em várias tabelas distintas e quando ocorre algum erro ao executar algum dos comandos preciso que seja feito o rollback de todas as alterações executado. Utilizo a seguinte anotação do Spring "@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)" para que ele faça isso de forma automática.
Esse comando funciona perfeitamente utilizando o banco de dados MySql ou Firebird, mas quando utilizo no Oracle não funciona!
Debugando o meu serviço vejo que a cada insert executado é feito um commit, vai direto para o banco de dados e não apenas ao finalizar o método, que seria a forma correta como funciona nos outros banco de dados. Pesquisei na internet descobri que existe a propriedade do hibernate chamada "hibernate.connection.autocommit" mas mesmo setando o valor como "false" para ela nada funciona (defini esse valor direto no arquivo "persistence.xml" e no "applicationContext.xml" na configuração do EntityManagerFactory, e em nenhum dos casos tive sucesso).
A configuração do Spring é a mesma para todos os banco de dados, o projeto é o mesmo e tudo funciona normalmente alterando o banco de dados, somente o controle das transações que não, pois aparentemente o Oracle não respeita a propriedade autocommit. É isso mesmo, o Oracle não respeita essa propriedade? Alguem tem uma ídea do que pode ser? Já tentei atualizar o driver OJDBC para a versão 14 mas o erro permanece.
Utilizo GlassFish 3.1.2, Oracle 11g, ojdbc6.jar, Hibernate 4.1.0, Spring 3.1.1.
Método do serviço:@Override
@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
public Entidade save(Entidade entidade) throws ServiceException {
try {
entidade = entidadeData.save(entidade);
outroService2.update(entidade.getCampo1(), entidade.getCampo2(), entidade.getCampo3());
atualizaOutroCampoEntidade(entidade);
return entidade;
} catch (Exception e) {
logger.error("Erro ao salvar entidade", e);
throw new ServiceException(e.getMessage());
}
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:task="http://www.springframework.org/schema/task"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd
http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd">
<context:annotation-config/>
<context:component-scan base-package="br.com.sistema.*"/>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="persistenceJpa"/>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="generateDdl" value="false"/>
</bean>
</property>
<property name="jpaPropertyMap">
<map>
<entry key="hibernate.connection.autocommit" value="false" />
<entry key="hibernate.connection.release_mode" value="after_transaction"/>
</map>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>
<tx:jta-transaction-manager/>
<tx:annotation-driven transaction-manager="transactionManager"/>
<jpa:repositories base-package="br.com.sistema.data" entity-manager-factory-ref="entityManagerFactory" transaction-manager-ref="transactionManager" />
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />
</beans>
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="persistenceJpa" transaction-type="JTA">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>jdbc/sistema</jta-data-source>
<class>xxxxx</class>
<properties>
<property name="hibernate.transaction.jta.platform" value="org.hibernate.service.jta.platform.internal.SunOneJtaPlatform"/>
<!--Na documentação do Hibernate 4.1 diz que pro 11G utiliza o mesmo dialeto do 10G -->
<property name="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect"/>
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.jdbc.batch_size" value="0"/>
<property name="hibernate.connection.charSet" value="WE8ISO8859P1"/>
<property name="hibernate.connection.useUnicode" value="true"/>
</properties>
</persistence-unit>
</persistence>