14 Replies Latest reply on Aug 4, 2010 11:38 AM by daniele campanini

    transaction commit  rollback

    daniele campanini Newbie

      Hi,
      In my applications I use Seam managed transaction and it's work very well.
      I some case after the commit on the db i must invoke a webservices but  How can I manage rollback? If somethings goes wrong i dont want call the webservices!!


      Example:


      public void save(){


      em.persist(..);
      web.callWebService();


      }

        • 1. Re: transaction commit  rollback
          Shervin Asgari Master

          You are already doing it.


          if persist fails exception is thrown and the next line is not executed.

          • 2. Re: transaction commit  rollback
            daniele campanini Newbie

            You are right Shervin!


            I have another question!
            If I undederstood right the data are stored on db only at the end of the method save(); suppose the webservices  web.callWebService() need the that same data, it could get from the db the old version of data!! right?
            How can i force the commit or manager the transacrion manually?



            public void save(){


            em.persist(anagrafica);
            web.callWebService();


            }


            @WebSevice(..
            public void callWebService(){
              em.find(anagrafica);


            }


            thanks in advance

            • 3. Re: transaction commit  rollback
              Shervin Asgari Master

              You can try to manually flush after persist.


              em.persist(obj);
              em.flush();
              



              • 4. Re: transaction commit  rollback
                daniele campanini Newbie

                I tried but it doesnt work; i think because the webservices execute in a different context (other applicatio server).


                I think should be possible manager the transaction manually, but i didnt found any documentation about that!!
                any ideas?


                • 5. Re: transaction commit  rollback
                  Shervin Asgari Master

                  Your webservice gets old data? Is that the problem?


                  What is exactly the problem?


                  em.persist(obj);
                  em.flush();
                  web.callWebService();





                  does not work?

                  • 6. Re: transaction commit  rollback
                    Shervin Asgari Master

                    daniele campanini wrote on Aug 04, 2010 04:27:


                    I think should be possible manager the transaction manually, but i didnt found any documentation about that!!
                    any ideas?




                    How you are injecting the EntityManager? If you are using Seam managed entityManager, I guess you are using @In?
                    Try using @PersistenceContext instead. I believe then that Seam will not manage the entityManager and you can manually control it.


                    Another way is by using a long-running conversation. Then in your @Begin you can write




                    @Begin(flushMode=FlushMode.MANUAL) 




                    Then nothing will be saved until you manually write flush();

                    • 7. Re: transaction commit  rollback
                      daniele campanini Newbie
                      The exact problem is the inconsistency on the data.


                      When the webservice get the data  from the db, it isnt't updated!! It's difficult to explain so I write a example more detailed.


                      Case 1

                      public void save(){

                      User user = em.find(User.class, "name1")
                      user.setSurname("newsurname");  
                      em.merge(user);
                      em.flush();

                      User user2 = em.find(User.class, "name1")
                      System.out.println("Surname is " + user2.getSurname());

                      }

                      it print; Surname is newsurname

                      Case 2


                      public void save(){

                      User user = em.find(User.class, "name1")
                      user.setSurname("newsurname");  
                      em.persist(user);
                      em.flush();

                      web.callWebService();

                      }

                      public void callWebService(){
                      User user2 = em.find(User.class, "name1")
                      System.out.println("Surname is " + user2.getSurname());

                      }

                      it print; Surname is oldsurname

                      The transaction begin when the method save() is invoked and the commit is at the end of the method; so the data are persisted on the db
                      after the webservices is invoked. the flush() should store the data in the hibernate cache (not on the db) so the webservice which run on other server cannot get the updated data!!


                      I should do something like that;

                      public void save(){
                      --> Begin transaction

                      User user = em.find(User.class, "name1")
                      user.setSurname("newsurname");  
                      em.persist(user);
                      em.flush();

                      --> commit transaction

                      web.callWebService();

                      }


                      So the question is: how can i begin and commit a transaction manually?

                      I tried the example above so i am sure about the problem, I hope my considerations are correct too!!

                      thanks for your time Shervin



                      • 8. Re: transaction commit  rollback
                        Shervin Asgari Master

                        I see.


                        The problem might be in the find method. I don't know how you have setup your application, but if second-level cache is enabled, then find will go and ask the second level cache, thus not hit the database.
                        You can try replacing the find with a manual query. It might work.


                        Do you see in the logs when you flush that insert is happening?

                        • 9. Re: transaction commit  rollback
                          daniele campanini Newbie

                          In the logs I see the insert when the flush() in invoked but the data are in the db only at the end of save() method.
                          To test the behavior I run the application in debug mode with a breakpoint after the flush, if i execute a query at that point with a sql editor (select surname from user) the result is still oldsurname!!




                          • 10. Re: transaction commit  rollback
                            Shervin Asgari Master

                            I see.


                            Ok then do this:




                            @RaiseEvent("saved")
                            public String save() {
                               //stuff
                               em.persist();
                            }
                            
                            @Observer("saved")
                            public void goWebservice() {
                               //Call webservice
                            }



                            If save() returns null or throws exception event is not raised.

                            • 11. Re: transaction commit  rollback
                              daniele campanini Newbie

                              I am sure it work and i'll use it, but i think it's a workaround so i'd like to understand how to manager a transaction manually.


                              Something like:


                              em.getTransaction().begin()


                              em.getTransaction().commit()


                              thanks a lot for your patience, you are really skilled!

                              • 12. Re: transaction commit  rollback
                                daniele campanini Newbie

                                Just tried your suggest, it doesnt work. I think the commit is after the method goWebservice().

                                • 13. Re: transaction commit  rollback
                                  Shervin Asgari Master

                                  Very strange.
                                  Perhaps you have enabled some strange caching which always asks the cache. Maybe your persist does not directly update the cache. Maybe there is a delay.


                                  Try putting the @Observer method in another Seam component so that the code is not in the same component.

                                  • 14. Re: transaction commit  rollback
                                    daniele campanini Newbie
                                    I maybe found a solution..hope no extra problem :-)


                                    @Stateful
                                    @Scope(ScopeType.SESSION)
                                    @TransactionManagement(TransactionManagementType.BEAN)
                                    @Name("testBean")
                                    public class TestBean implements ITestBean{

                                      @PersistenceContext(type = PersistenceContextType.TRANSACTION)
                                      private EntityManager em;
                                       
                                      @Resource
                                      private SessionContext sctx;
                                       
                                      ..


                                       public void save() throws Exception{
                                           javax.transaction.UserTransaction ut = sctx.getUserTransaction();
                                          
                                           ut.begin();
                                           //persist

                                           ut.commit();
                                           //call webservice

                                       }

                                    }