6 Replies Latest reply on Jan 24, 2007 6:51 PM by Xiaoguang Sun

    How to really flush data in the middle of a transaction

    Xiaoguang Sun Newbie

      I'm using MySQL database and I have a method which uses EntityManager to persist newly generated entities. And after doing that, I raised an event to ask another component to load entities using @Observer. But seems I can't get the newly persisted data. I guess maybe the reason is because the observer method running under the same uncommited transaction.

      I tried calling flush() method of EntityManager before raise event, but still didn't work.

      Is there anybody knows how to solve this? Thanks in advance

        • 1. Re: How to really flush data in the middle of a transaction
          Gavin King Master

          Sounds like the observer method is actually running in a *different* transaction. Or maybe there is no transaction at all.

          • 2. Re: How to really flush data in the middle of a transaction
            Xiaoguang Sun Newbie

            Thanks Gavin King for your hint.

            So I checked MySQL transaction settings and just noticed there is a isolation level setting in MySQL. And after changing it to READ UNCOMMITTED, I get the most uptodate data.

            • 3. Re: How to really flush data in the middle of a transaction
              jk;l jkl; Expert

              Don't set your MySQL transaction setting to READ UNCOMMITTED unless you really want to allow dirty reads (do you!?).

              I think you might've solved the wrong problem...setting READ UNCOMMITTED works because they're running in separate transactions like the previous post said. You should figure out how to get the observer method in the same transaction so you can leave the transaction isolation at whatever it was before.

              Anybody have suggestions on how might you do this? Can you just annotate observer methods with transaction attributes or is that only for session beans?

              • 4. Re: How to really flush data in the middle of a transaction
                Xiaoguang Sun Newbie

                to lightbulb432,

                Yea. You are right. I hate to change the default isolation level.

                I tried to manually commit the transaction before I raiseEvent, but the transaction was managed by Seam, so I can't do this manually. And the default REPEATABLE-READ makes the observer running in another transaction won't be able to read the uncommited data if it get executed before the commit.

                Let me try to find if there is any other way to force the other component use the same transaction which raises event.

                • 5. Re: How to really flush data in the middle of a transaction
                  Gavin King Master

                   

                  Don't set your MySQL transaction setting to READ UNCOMMITTED unless you really want to allow dirty reads (do you!?). I think you might've solved the wrong problem...setting READ UNCOMMITTED works because they're running in separate transactions like the previous post said.


                  Exactly. Dirty reads are VERY BAD. Read what I wrote about them in Hibernate in Action / Java Persistence with Hibernate.


                  Anybody have suggestions on how might you do this?


                  Most events are processed synchronously by Seam, so you would have to be doing something "funny" to get a different transaction context. Perhaps he has an asynchronous event. Or perhaps he has no transaction at all. Or perhaps the observer method has REQUIRES_NEW. No code, can't tell.

                  Can you just annotate observer methods with transaction attributes or is that only for session beans?


                  An observer method can be on a session bean. And even if it is not, you can annotate methods of JavaBean components with transaction attributes in Seam 1.1. But you should not need to do this. The default behavior is to propagate the transaction, for all component types.

                  By the way, another possibility in Seam 1.1.1 is to use an event that is processed after the transaction commit. This is an excellent way to handle refresh of session or application scoped state after the end of a conversation. The booking example uses this.


                  • 6. Re: How to really flush data in the middle of a transaction
                    Xiaoguang Sun Newbie

                    To Gavin King,

                    Clear explanation!!
                    Now I understand what was wrong.

                    I placed REQUIRES_NEW as transaction attribute. And after removing this, everything works well. And since 1.1.1 can process event after commit, I think it is the time for me to upgrade now.

                    Thanks again.