Win a copy of Mesos in Action this week in the Cloud/Virtualizaton forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Calling a Bean's Method with Different Transaction Attributes?

 
James Dekker
Ranch Hand
Posts: 221
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
What happens if a transactional method with certain transaction attributes call a method at the same bean with different transaction attributes?
 
Bill Gorder
Bartender
Posts: 1682
7
Android IntelliJ IDE Linux Mac OS X Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Well that would depend what those 'transactional attributes' are. Are we talking about propogation? Have a look

Here:

http://static.springsource.org/spring/docs/3.1.x/javadoc-api/org/springframework/transaction/annotation/Propagation.html

and here:

http://static.springsource.org/spring/docs/3.1.x/spring-framework-reference/html/transaction.html#tx-propagation

Generally speaking the the outer transaction configuration determines the actual one used.


 
Mark Spritzler
ranger
Sheriff
Posts: 17278
6
IntelliJ IDE Mac Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
James Dekker wrote:What happens if a transactional method with certain transaction attributes call a method at the same bean with different transaction attributes?


Actually, what you have here is a "code smell" basically there is something wrong with the design. So If I have one bean with two public methods a() and b() and both are Transactional. a() calls b(). That call to b will not go through the proxy, you are already in that bean instance. So it will not go out and recall it through the proxy, it calls it directly. So b() in a sense will be in the context of a()s transaction, because it is still in a sense in a().

once you are within the actual instance of the bean it will call other methods in that same instance directly.

So why is that a code smell. 2 possible reasons . 1) a() should not be a client to b(). Basically you are breaking interfaces and their purpose. a public interface is for clients outside of the class. or 2) b() should NOT BE in the public interface. a() is the only "client" of b() and therefore b() should have been declared private.

So the fix, move b() into another interface/another class so that a() can be a public client of b(), or make b() private.

Mark
 
Bill Gorder
Bartender
Posts: 1682
7
Android IntelliJ IDE Linux Mac OS X Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
at the same bean


I missed that

I agree with Marks analysis I thought we were talking about nested transactions across services or layers.

Mark,

The bit about not going through the proxy is specific to interface based proxying correct? I can't recall ever having tried it but I would think using CGLIB and AspectJ class based proxies would allow you to have a nested @Transactional private method in the same bean. I know the aspect j marker would be there and I just always assumed it would work. I know I have had private Transactional methods within services before on a few occasions but that is usually to keep the transaction open for the smallest amount of time needed on service calls which can take some time to complete , and in that case the service method exposed by the interface is not transactional.
 
It is sorta covered in the JavaRanch Style Guide.
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic