This week's book giveaway is in the Other Languages forum.
We're giving away four copies of Functional Reactive Programming and have Stephen Blackheath and Anthony Jones on-line!
See this thread for details.
Win a copy of Functional Reactive Programming this week in the Other Languages forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Spring Hibernate Transaction

 
shakir hussain
Greenhorn
Posts: 10
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I have three service classes namely -
1. OrderService with method order()
2. CustomerService with method acceptCustomerInfo()
3. PaymentService with method pay()

Name of implementation classes are OrderServiceImpl, CustomerServiceImpl, PaymentServiceImpl.
From these Implementation classes, DAO layer methods are called

1. OrderDAO - order()
2. CustomerDAO - acceptCustomerInfo()
3. PaymentDAO - pay()
Name of implementation classes on DAO layer are : OrderDAOImpl, CustomerDAOImpl, PaymentDAOImpl
These classes actually interacts with the database either through hibernate or simple jdbc

Now, on front end
i have one button CHECK-OUT, when user clicks on this button all three methods on service layer gets executed in single transaction.
If anyone fails, all should rollback.

how to design/work to ensure this scenario to work correctly???
 
Mark Spritzler
ranger
Sheriff
Posts: 17278
6
IntelliJ IDE Mac Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Easiest would be to set the three service methods to be Transactional each with the Required Propagation, which is the default, so you can just accept the default values for say @Transactional, on all three Service classes and it will work as you expect. If you need it to work differently, then it might be set differently, but how you explain it, just taking the defaults it perfect.

Mark
 
James Boswell
Bartender
Posts: 1051
5
Chrome Eclipse IDE Hibernate
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Mark

Are you definitely correct here?

If all 3 service methods are marked as @Transactional and say, the second or third method rolls back, aren't the previous method(s) committed?

Don't you need to have a single wrapper service method (e.g. checkout()) that is marked as @Transactional and calls each of the other 3 service methods so that if one fails to commit, the entire state change made by checkout() is rolled back?
 
shakir hussain
Greenhorn
Posts: 10
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks for quick reply to everyone. But friends, the database is updated on DAO layer where user can use either plane JDBC or Hibernate....

Do I not need any changes on DAO layer( for transaction) or it will be handled by spring itself?
 
Atul Kotwale
Greenhorn
Posts: 17
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I agree with james. You just need a wrapper method with @Transactional attribute and which would call all the three method. No need to change any thing on DAO layer.
 
James Boswell
Bartender
Posts: 1051
5
Chrome Eclipse IDE Hibernate
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Atul

Regardless of whether my solution or Mark's works, you should always handle transactions IMO in the service (business) layer, not in DAOs.
 
Mark Spritzler
ranger
Sheriff
Posts: 17278
6
IntelliJ IDE Mac Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
James Boswell wrote:Atul

Regardless of whether my solution or Mark's works, you should always handle transactions IMO in the service (business) layer, not in DAOs.


My suggestion does have the transaction demarcation on the service layer. And yes, if he had @Transactional on all three service methods, where one calls the other and they are in different service classes, then it will all run in just one transaction. Since the default value for propagation is REQUIRED, which means if there is already a transaction then join it. If there isn't one started, then start a new one. Since the first call would start a new transaction, the next calls to the other service from that first service would run within the very transaction that the first service started.



if I call a.doA() then a, b and c methods will all run in one single transaction. So anything that happens in A, B or C that would cause a rollback, then all three would rollback. That is how propagation REQUIRED works.

Mark
 
Mark Spritzler
ranger
Sheriff
Posts: 17278
6
IntelliJ IDE Mac Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Now if his button calls A, then the button calls B, then the button calls C, then that will not work because now the button is in control. It also wouldn't be a clean design to do that from a button. Which is the suggestion of a wrapper service to call A then B then C, in which the method in the wrapper service could be annotated with @Transactional, and he wouldn't need @Transactional on A, B and C, unless he has code elsewhere that call A, B or C and needs transactions, but if he annotates A, B and C with @Transactional, he would also have those and the first wrapper service all handled correctly. But it is specifically all these possible scenarios that it is important to understand propagation settings and what each mean.

Mark
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic