PDA

View Full Version : transactions implementation


geideon
Mar 22nd, 2005, 01:20 AM
Hello,

On a service object, i have a sequence: methodA->methodB->methodC ->method D. B and C are transactionnal methods.
I prefer declarative transactions in the context and i had to refactor the service object into 2 interfaces (A and D + B and C) with separate implementations.
Is there a prettiest way to do this: How can i leave A,B,C,D implementations in the same class without programmatic transactions ?
thanks.

Alarmnummer
Mar 22nd, 2005, 05:38 AM
Hello,

On a service object, i have a sequence: methodA->methodB->methodC ->method D. B and C are transactionnal methods.

Are B and C being executed from the same transaction? Or do they have their own?


I prefer declarative transactions in the context and i had to refactor the service object into 2 interfaces (A and D + B and C) with separate implementations.

You can add transactions to specific methods.. you aren`t forced to add transactions on all methods.


Is there a prettiest way to do this: How can i leave A,B,C,D implementations in the same class without programmatic transactions ?
thanks.
If you don`t know how to add transactions only to specific methods, I would suggest: check the documentation (see chapter 7.4. Declarative transaction managemen).

If you want something else, please give more information, because I don`t think I`m understanding your problem correctly.

geideon
Mar 22nd, 2005, 08:09 AM
Sorry i didn't well explain (hard in english :( )
I have a service object (so1) implementing A,B,C,D with B and C standalone transactions

In A method of so1 the code is
...
this.B;// transactionB
...
this.C;//transactionC
...
this.D;
...
To make this work, i had to put B and C in another service object (so2) so i could proxify them to obtain my transactions.

In A the code is
...
so2.B;
...
so2.C;
...
this.D;

I thought perhaps there will be a solution without refactoring my transactionnal methods in another service object ?
Perhaps another solution would be to inject a proxy of so1 on so1 implementation to have a kind of reentrance through the proxy?
In method A of so1
this.so1Proxy.B
this.so1Proxy.C
this.D


(Sorry if it is not clear, I'm newbie to spring)

Alarmnummer
Mar 22nd, 2005, 08:40 AM
Sorry i didn't well explain (hard in english :( )
I have a service object (so1) implementing A,B,C,D with B and C standalone transactions

In A method of so1 the code is
...
this.B;// transactionB
...
this.C;//transactionC
...
this.D;

Do you find it acceptable that if C is going to fail, B is not rolled back? Therefor A is not atomic.. I don`t know if this is acceptable in your design.


To make this work, i had to put B and C in another service object (so2) so i could proxify them to obtain my transactions.

Check the documentation. You can add transactions on the method you desire.

example:

<bean id="petStore" class="org.springframework.transaction.interceptor.Transa ctionProxyFactoryBean">
<property name="transactionManager"><ref bean="transactionManager"/></property>
<property name="target"><ref bean="petStoreTarget"/></property>
<property name="transactionAttributes">
<props>
<prop key="b*">PROPAGATION_REQUIRED</prop>
<prop key="c*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>


Now only b and c have a transaction. Other methods (a d) don`t have a transaction. Is this not what you want?

geideon
Mar 22nd, 2005, 10:38 AM
Thank you for giving time to help.
yes, it is acceptable if c failed b not rolled back.
In fact, the service object i'm talking about is a batch that does for example B (new adhesions) and C (modifications of existing adhesions)

In your example, the transaction will not even start in my case because B and C are called from A inside the implementation (so it will not be transactionnal adviced except if i call B on the transactionnal proxy from A) ?

Below is part of my context

(The interface IServicesAdhesion defines B and C and is implemented in so2.)
I was looking for a solution without the need of so2, so1 implementing B and C)

<bean id="so1Impl" class="fr.gouv.toto.impl.ServiceAdhesionImpl">
<property name="nomBatch">
<value>${adhesion.nombatch}</value>
</property>
<property name="so2">
<ref local="so2Advice"/>
</property>
</bean>
<bean id="so2Advice" class="org.springframework.transaction.interceptor.Transa ctionProxyFactoryBean">
<property name="target">
<ref local="so2Impl"/>
</property>
<property name="proxyInterfaces">
<value>fr.gouv.toto.services.IServicesAdhesion</value>
</property>
<property name="transactionManager">
<ref bean="transactionManager"/>
</property>
<property name="transactionAttributeSource">
<value>fr.gouv.toto.services.IServicesAdhesion.*=PROPAGAT ION_REQUIRED</value>
</property>
</bean>
<bean id="so2Impl" class="fr.gouv.toto.services.adhesion.impl.ServicesAdhesi onTraitementFichierTransactionnels"/>

Alarmnummer
Mar 22nd, 2005, 11:28 AM
In your example, the transaction will not even start in my case because B and C are called from A inside the implementation (so it will not be transactionnal adviced except if i call B on the transactionnal proxy from A) ?

Hmmm.. that is a good point.. I haven`t thought about that (I haven`t done much with transactions and Spring).

katentim
Mar 23rd, 2005, 04:35 AM
I thought perhaps there will be a solution without refactoring my transactionnal methods in another service object ?
You can get the advised object by calling AopContext.currentProxy(), with the exposeProxy flag on your proxy config set to true. See this post (http://forum.springframework.org/viewtopic.php?t=90#348).

geideon
Mar 23rd, 2005, 12:50 PM
thank you.