13 Replies Latest reply on Jul 30, 2009 11:45 PM by zilet

    flushMode=MANUAL does not work as expected

      Hi All,

         seam version I am using in the project is 2.1.0.SP1 but I have also tried the same thing with seam 2.1.2 and the behaviour is the same.

         I use SMPC and us @In for entity manager. When I use flushMode=MANUAL it doesn't work by default. I have some forms which are using Ajax to change some properties on the entity itself. All of this is done in the conversation which has flushMode set to Manual. When I end the conversation the changes are persisted to the database. This is not desired and also not as documented.

         I have find out that setting transaction-management-enabled="false" flushMode works as expected but the application response becomes unacceptably slow. I don't understand why is this happening. I was thinking that by not managing the transaction the response will be even faster but the opposite happens !?!
         
         Application is run inside Jboss 4.2.3 and have <transaction:ejb-transaction /> option.

         Is there something else to be configured in order for flushMode=Manual to work as expected?

         Thanks.  
        • 1. Re: flushMode=MANUAL does not work as expected
          superfis

          What database are you using in this project?

          • 2. Re: flushMode=MANUAL does not work as expected
            cash1981
            Do you have a long running conversation? @Begin(join = true) ?
            If you don't want to persist the changes, then either refresh, or dont end the conversation. If you have an interaction then it should be a long running conversation. You instead have join=true and not end, and only end when you are totally finished and want to persist. It should work that way
            • 3. Re: flushMode=MANUAL does not work as expected
              superfis

              Slawek Trybus wrote on Jul 05, 2009 14:28:


              What database are you using in this project?



              Considering e.g. MySQL it's not working out of the box due to no sequences for entity id generation in this database. In such situation you should use sequence-like generator as it's described here. In other case there will be use default auto table id generation and will cause some commits in the middle of your long running conversation with flush=MANUAL.

              • 4. Re: flushMode=MANUAL does not work as expected
                asookazian

                Post code.  this is either a user issue or bug.

                • 5. Re: flushMode=MANUAL does not work as expected

                  The database in the project is MSSQL and the issue doesn't have anything to do with sequences.


                  As I said the problem is because seam invokes flush even when it is set to flush mode manual.


                  Conversation is long running and as I said there is a workaround for this and that is to disable the transaction management by setting :



                  transaction-management-enabled='false'



                  (this disables just the JSF transactions as I read somewhere) but is causing the unacceptable slowness.


                  When You use EJB instead of SMPC and manually set flush mode to manual by using getDelegate.setFlushMode(MANUAL) everything works as expected. If You try this approach with seam flushing happens as with using the SMPC.


                  Flushing doesn't happen only if transactions are disabled.


                  As I was reading through the forum Seam uses 2 transactions per request and if the first one is not disabled by the parameter mentioned above, I think that seam calls em.flush() in the end of that first transaction !?


                  This is mentioned in the Chapter 9



                  use two transactions per request; the first spans the beginning of the restore view phase (some transaction managers begin the transaction later at the beginning of the apply request vaues phase) until the end of the invoke application phase; the second spans the render response phase

                  But again since there is some problem with dealocating statefull EJBS on high loads on JBoss 4.2.3 I have to use SMPC. (this is how the app runs right now but the jboss is being monitored daily and has to be restarted if it reaches the memory maximum)


                  I think that this is a serious issue and I'll try to make small demo to illustrate the problem.

                  • 6. Re: flushMode=MANUAL does not work as expected
                    asookazian

                    The issue may have to do with using Hibernate MANUAL flushMode and IDENTITY columns in MSSQL (I do exactly this!)


                    @GeneratedValue(strategy = GenerationType.IDENTITY)



                    SiA book:



                    If the entity identifier is generated during an insertion (i.e., auto-increment
                    column), then even with manual flushing, a flush occurs after a call
                    to persist(). This is necessary since each managed entity in the persistence
                    context must be assigned an identifier. To avoid the flush, you
                    need to set the id-generation strategy to sequence (not identity).

                    I'm pretty sure that Seam does not flush the PersistenceContext via em.flush() during the Seam life cycle (see below).  This would obviously be undesired behavior (i.e. defeat the application tx as described by DAllen in SiA) and most likely a bug.


                    Are you using CMT with session beans as your backing beans?  Or Seam's @Transactional with JavaBean components?


                    With EJB3, as per JSR220, there are only two transactional commit modes: COMMIT and AUTO.  With the Hibernate extension, you have the option of MANUAL (which will not be introduced into JPA 2.0).  So this means that the only way that the PersistenceContext will be flushed is via em.flush() (i.e. a manual flush programmatically) or via the situation quoted above with IDENTITY columns. 


                    Are you sure that your current LRC is annotated like the following?


                    @Begin(join=true, flushMode=FlushModeType.MANUAL)



                    There are repurcussions of doing the following:


                    <core:init transaction-management-enabled="false"/>



                    read section 9.4.1 Global transactions in SiA book.


                    There is a reason the Seam designers implemented global tx's.  To prevent this: lazy-load operations execute in autocommit mode,
                    opening and closing a transaction for every query
                    and use a single tx instead during that phase of the JSF life cycle.


                    There are actually 3 tx's in total as depicted in Figure 9.2 in SiA.  This part of the Seam framework (tx mgmt specifically) is difficult to understand.


                    As far as a performance improvement if you turn off Seam tx mgmt, I'm not sure but I wouldn't be surprise (if you don't use @In or @Out you will likely see at least modest performance gains).


                    Note the following:



                    During the Seam life cycle, Seam applies two key aspects of its global transaction strategy:
                    ■ Wraps each request in two (or three) distinct transactions
                    ■ Disables flushing of the persistence context during view rendering


                    The final transaction ensures that database reads occurring in the Render Response
                    phase—as a result of lazy loading and other on-demand fetch operations—remain isolated
                    to protect against interim database changes as defined by the transaction isolation
                    level. Seam also disables flushing of Seam-managed persistence contexts during
                    the Render Response phase if Hibernate is the persistence provider, effectively making
                    the transaction read-only. This measure ensures that the view can’t inadvertently cause
                    the database to be modified.
                    • 7. Re: flushMode=MANUAL does not work as expected
                      jeanluc

                      Enable DEBUG logging for org.jboss.seam and for JSF (I don't remember the log4j category now, but it's not under org.jboss.seam). Or, as a quick check, enable DEBUG logging for the root logger. Enabling TRACE for org.hibernate might be of use as well.


                      Then post the log here and/or read careful through it. This should provide more light into what is happening and hopefully into why as well.

                      • 8. Re: flushMode=MANUAL does not work as expected

                        Hi again,


                        I didn't have time to go more into this problem because of other work.. Now when I revisited it again I found where was the problem.


                        In the project we use multiple data sources. One data source is just for reading operations so it is declared as a non-tx data source. The business methods that were used to retrieve data from that DS are Stateless EJBs and they all are using containers persistence context.


                        The main data source uses Seams PC and has @In for entity manager.


                        It seams that seams spans its transaction over both data sources and since one uses @PersistenceContext it switches back to the AUTO flush mode.


                        I replaced @PersistenceContext for the other data source with Seams PC and the manual flush works as expected.


                        • 9. Re: flushMode=MANUAL does not work as expected
                          asookazian

                          Milos Zikic wrote on Jul 25, 2009 14:24:


                          In the project we use multiple data sources. One data source is just for reading operations so it is declared as a non-tx data source. The business methods that were used to retrieve data from that DS are Stateless EJBs and they all are using containers persistence context.

                          The main data source uses Seams PC and has @In for entity manager.

                          It seams that seams spans its transaction over both data sources and since one uses @PersistenceContext it switches back to the AUTO flush mode.

                          I replaced @PersistenceContext for the other data source with Seams PC and the manual flush works as expected.




                          That's an interesting scenario that I've never tried.  I have had multiple datasources in a project but I've always exclusively used @In rather than @PersistenceContext to inject my EntityManager instances.


                          It would be good if you could post code that demonstrates this happening:



                          seams spans its transaction over both data sources and since one uses @PersistenceContext it switches back to the AUTO flush mode.

                          If this is true, then the Seam ref doc should be updated to reflect this.  I haven't read this anywhere (and I guess that's b/c everyone recommends using @In exclusively).


                          Wait a minute.  Are you using 2PC/XA datasources here?  IIRC that's the only way you can enlist 2 datasources in the same tx using EJB/JTA.


                          Post your *-ds.xml and persistence.xml please.

                          • 10. Re: flushMode=MANUAL does not work as expected
                            The project uses 2 PC which are not XA.
                            Both databases are SQL server DBs and I didn't want to go on with XA implementation on those and since one DS is just for read only use than one ds is declared as <no-tx-datasource> and the other one as a <local-tx-datasource>.

                            This is also the way to make seam work with 2 data sources without XA transactions.

                            the no-tx business logic was implemented separately and was using the EJB without seam but because of this problem we had to convert it to seam.

                            So nothing special but not that obvious.
                            • 11. Re: flushMode=MANUAL does not work as expected

                              Oh and one more thing.. MANUAL flush mode seems not to work on Java 1.5.


                              This works great only on Java 1.6

                              • 12. Re: flushMode=MANUAL does not work as expected
                                asookazian

                                Milos Zikic wrote on Jul 27, 2009 19:02:


                                Oh and one more thing.. MANUAL flush mode seems not to work on Java 1.5.

                                This works great only on Java 1.6


                                Are you saying manual flush has problems with JDK 1.5 and your project?  Not generally speaking, right?  Either way that's an interesting finding.

                                • 13. Re: flushMode=MANUAL does not work as expected

                                  Yes, somehow this is true.


                                  I don't have time to investigate more on this topic but will revisit it definitely again.