Ajuda Spring + Transacoes

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"); } }

[code]@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;
}[/code]

[code]
@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;
}

}[/code]

[code]@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;
}

}[/code]

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

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.

mal mlkao pensei q eu tinha posto ele tbm

[code]<?xml version="1.0" encoding="UTF-8"?>

<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>

[/code]

tae …

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.

Perfeito… porem eu coloquei ali

@Transactional(propagation = Propagation.MANDATORY)

e o significado [quote]
MANDATORY
Support a current transaction, throw an exception if none exists.[/quote]

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

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.

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

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.

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

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

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

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