Ajuda Spring + Transacoes

11 respostas
fabioebner
Pessoal, estou comecando com Spring e gostaria de tirar uma duvida com vcs.. tenho as seguintes classes:
@Component
public class Main {
    public static void main(String[] args) {
        // TODO code application logic here
        ApplicationContext ac = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
        Tabela1FACADE tb = (Tabela1FACADE) ac.getBean("tabela1FACADE");
        tb.novo("asa", "34");
    }
}
@Service
public class testar {

    @Autowired
    private Tabela1FACADE tabela1FACADE;

    public void testa() {
        try {
            this.tabela1FACADE.novo("Aeeee", "iiiii");
        } catch (Exception e) {
            e.printStackTrace();
        }
         
    }
 
    public Tabela1FACADE getTabela1FACADE() {
        return tabela1FACADE;
    }
    public void setTabela1FACADE(Tabela1FACADE tabela1FACADE) {
        this.tabela1FACADE = tabela1FACADE;
    }
@Repository("tabela1DAO")
public class Tabela1DAO {

    private HibernateTemplate hibernateTemplate;

    @Autowired
    public void setHibernateTemplate(SessionFactory sessionFactory) {
        this.hibernateTemplate = new HibernateTemplate(sessionFactory);
    }


    public void save(TbTabela1 entity){
        this.hibernateTemplate.save(entity);
    }

    public HibernateTemplate getHibernateTemplate() {
        return hibernateTemplate;
    }
    
}
@Service
@Scope("prototype")
public class Tabela1FACADE {
    
    @Autowired
    private Tabela1DAO tabela1DAO;

    @Transactional(propagation = Propagation.MANDATORY)
	public TbTabela1 novo(String nome, String descricao) {
		TbTabela1 tabela1 = new TbTabela1();

       tabela1.setNmTabela1(nome);
       tabela1.setDsTabela1(descricao);

		tabela1DAO.save(tabela1);
		System.out.println("passou");
		return tabela1;
	}
    public void setTabela1DAO(Tabela1DAO tabela1DAO) {
        this.tabela1DAO = tabela1DAO;
    }
    public Tabela1DAO getTabela1DAO() {
        return tabela1DAO;
    }
}

Nessa ultima eu coloquei o tipo de Transacao como mandatory.. pelo q eu li mandatory ele necessita de uma transacao ja aberta. senao ele da erro.. agora pergunto eu.. nao teria q dar um erro ali?

pq eu so abro a transacao ali para dar o save, e nao estou recebendo ela de algum outro lugar.

teria q dar erro nao teria?? alguem me ajuda??

valeu

11 Respostas

B
Não é você quem abre a transação. Se está funcionando é porque sua transação está sendo gerenciada pelo Spring (ou hibernate), de acordo com a configuração no seu applicationContext.xml. Poste-o para ficar mais claro o que está acontecendo.

Não é você quem abre a transação. Se está funcionando é porque sua transação está sendo gerenciada pelo Spring (ou hibernate), de acordo com a configuração no seu applicationContext.xml. Poste-o para ficar mais claro o que está acontecendo.

fabioebner
mal mlkao pensei q eu tinha posto ele tbm
<?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:context="http://www.springframework.org/schema/context"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xmlns:tx="http://www.springframework.org/schema/tx"
	xsi:schemaLocation="
		http://www.springframework.org/schema/beans
		http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
		http://www.springframework.org/schema/context
		http://www.springframework.org/schema/context/spring-context-2.5.xsd
		http://www.springframework.org/schema/aop
		http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
		http://www.springframework.org/schema/tx
		http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
		">

	<context:annotation-config/>
	<context:component-scan base-package="br.."/>
	<aop:aspectj-autoproxy/>


    <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean" >
    <property name="dataSource">
     <ref local="c3p0DataSource"/>
    </property>
 	 <property name="annotatedClasses">
		    <list>
		       <value>br.entity.TbTabela1</value>
		     </list>
		   </property>

    	<property name="hibernateProperties">
    		<props>
 			    <prop key="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</prop>
    			<prop key="hibernate.connection.autocommit">false</prop>
    		</props>
        </property>

    </bean>


    <bean id="c3p0DataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
    	<property name="driverClass" value="org.postgresql.Driver"/>
    	<property name="jdbcUrl" value="jdbc:postgresql://localhost:5432/db_dnaso"/>
    	<property name="user" value="postgres"/>
    	<property name="password" value="dna44100"/>
        <property name="initialPoolSize" value="5"/>
        <property name="minPoolSize" value="5"/>
        <property name="maxPoolSize" value="15"/>
        <property name="checkoutTimeout" value="1000"/> 
        <property name="maxStatements" value="50"/>
        <property name="testConnectionOnCheckin" value="true"/>
        <property name="idleConnectionTestPeriod" value="60"/>
    </bean>

    <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    	<property name="sessionFactory" ref="sessionFactory"/>
    </bean>



</beans>

tae ..

B

Como podemos ver, você declarou o hibernate como gerente de transação. Toda vez que um método do seu serviço é chamado uma transação é ligada à esse método.

fabioebner

Perfeito… porem eu coloquei ali

@Transactional(propagation = Propagation.MANDATORY)

e o significado


MANDATORY
Support a current transaction, throw an exception if none exists.

entao se nenhuma transacao ja estiver ocorrendo ele teria q me retornar um erro nao teria???

B

Sim, entretanto como eu disse a cada chamada de método no seu serviço uma transação será criada e terminada no retorno do método. Se você estivesse utilizando Spring puro (sem um gerente de transação do hibernate) provavelmente ocorreria a exceção IllegalTransactionStateException, que é a sua dúvida.

fabioebner

E como eu faco para colocar o gerenciamento pelo spring?? pq eu estava testando aqui tbm. por exemplo um projeto chamando outro… e nao funciona o rollback tbm… gerei uma Exception so para testar, e ele nao deu rollback em lugar nenhum. e gostaria de o spring gerenciar isso pra mim

valeu

B

Veja bem, quando eu digo que é o hibernate que gerencia suas transações significa que isso ocorre sobre um proxy do spring. Quando nenhum transactionManager é declarado fica por conta do spring somente gerencias estas transações, mas isso só é usado quando se quer implementar funcionalidades específicas como o pattern OpenSessionInView.

fabioebner

Entao cara pq qual o meu problema, eu trabalho cmo desktop, entao tenho varios projetos diferentes, porem um pode utilizar o outro ou nao… e qdo um utilizar o outro eu quero q o filho participe da transacao do pai, por isso q estava testando essa parte do MANDATORY E tal, porem mesmo eu colocando mandatory, required, etc etc, ele salva no banco… tentei simular tbm um rollback, porem tambem nao obtive sucesso…

sera q vc poderia me dar uma luz de como fazer isso? pelo q vc falou com o gerenciamento de transacao pelo spring, eu conseguiria resolver isso atraves das configuracoes neh?

valeu

B

Aqui tem tudo que você precisa.
De acordo com a sua necessidade sugiro utilizar de transação programática ao invés de declarativa.

fabioebner

Entao bkn, o spring ja nao tem todo esse controle?? pelo q eu ouvi falar, pois o meu problema tbm e q por exemplo eu tenho diversos projetos, um pode usar o outro… porem todos podem rodar individualmente, e com essa parte de propagation, e tal… pelo q eu li, serve pra isso, se ja tiver uma transacao utiliza ela, se nao tiver cria outra… e como participa da mesma transacao eu precisar dar rollback em qualquer lguar ele desfaz as outras tbm…

vlw

fabioebner

ae mlkao consegui resolver um dos problemas, eu nao tinha posto a tag tx:annotation-driven/ no meu xml :smiley: eheheheh coloquei e funcionou uma parte do meu problema :smiley:

valeu

Criado 3 de agosto de 2009
Ultima resposta 4 de ago. de 2009
Respostas 11
Participantes 2