12 Replies Latest reply on Dec 31, 2008 9:47 AM by arshadm

    Several transactions with manual flush

    vanyatka

      Hi,


      According to Seam in Action we can issue several transactional methods not sending any data to the database using manual flush:


      <begin-conversation join="true" flush-mode="manual"/>
      With this configuration in place, database transactions may come and go, but the
      changes to the entity instance aren’t migrating to the database until the flush()
      method on the persistence manager is called.



      Let's say we ran several transactional methods and flushed them later at some point. What if the first transaction failed? Does it mean all the rest of the transactions failed too? Or they are all independent?


      It's all very confusing, cause we normally have to know whether one transaction failed/succeeded before moving along to the next one.


      Any clarifications are highly appreciated )



        • 1. Re: Several transactions with manual flush
          javacoryd

          Flush mode="manual" really means that any pending updates/inserts/deletes that are in the EntityManager will not be executed until you issue an entityManager.flush() operation.  When you flush() all of the SQL statements are executed against the datasource and within the same transaction.


          Flush mode="manual" should be used when you have a conversation that spans multiple pages ( submits ), but you don't want the changes persisted until a final confirmation page.  All throughout the conversation, the entity beans are being updated, but not persisted ( flushed ) until you flush().


          Hope this helps.


          Cory.

          • 2. Re: Several transactions with manual flush
            vanyatka

            Cory, thanks for your clarifications on general manual flush. But can you comment on the initial question, what happens when several transactions are pending and the first one of them fails?


            And again, I simply cannot get the idea of running next transaction before knowing if the previous one committed/rolled back.


            Please let me know if I should be more clear in explaining the issue.

            • 3. Re: Several transactions with manual flush
              javacoryd

              The text is slightly misleading from the sense that there are multiple database transactions if you consider one insert or one update a transaction.  However, all inserts and updates should execute under the same atomic ( JTA ) transaction which would make them all either fail or not.


              Cory.

              • 4. Re: Several transactions with manual flush
                vanyatka
                However, all inserts and updates should execute under the same atomic ( JTA ) transaction which would make them all either fail or not.



                With manual flush we can have several database transactions pending and then executed in one go. Is that correct?

                • 5. Re: Several transactions with manual flush
                  joblini


                  With manual flush we can have several database transactions pending and then executed in one go. Is that correct?


                  Let's be sure not to confuse DML operations, such as insert, update and delete, with transactions. 


                  Only one database transaction is active at a time.  A transaction spans 0 or more DML operations. 


                  With flush mode set to manual, no DML operations will be performed unless flush is called.


                  Flush mode does not determine when transactions are started and ended.


                  Transactions are started and ended during the Seam-Faces request-response cycle, regardless of the flush setting.  All database accesses are done within a transaction, even when only to read data, such as during the restore view phase.


                  Runtime exceptions, and application exceptions so defined, will cause the current transaction to be rolled back.


                  • 6. Re: Several transactions with manual flush
                    vanyatka

                    Ingo, thank you for your generous reply! I sense we're getting closer to the truth of the matter )


                    Let's be sure not to confuse DML operations, such as insert, update and delete, with transactions.
                    



                    No problem with that. But apart from DML operations ORM must issue transaction demarcation statements, like BEGIN TRANSACTION, COMMIT OR ROLLBACK. And if my understanding is correct NONE of those statements are issued either, until explicitly ordered by flush(). In other words when I flush ORM might send something like this:


                    BEGIN TRANSACTION
                    INSERT
                    DELETE
                    COMMIT
                    
                    BEGIN TRANSACTION
                    INSERT
                    DELETE
                    COMMIT



                    So the question is: What if some of DML statements within the 1st transaction fail, causing  it to rollback? Will statements from the 2nd transaction run (cause they don't actually belong to the first transaction, right) or all the rest of DML statements in the queue will be ignored?



                    • 7. Re: Several transactions with manual flush
                      arshadm

                      Hi,


                      You are confusing flush mode and transactions. Flush mode has nothing to do with transactions per say.


                      With manual flush mode, any changes you make to the beans and saved are NOT persisted to the database at the end of that response.


                      The whole request-response may have happenned and you may have made changes to several beans and saved them but that state has NOT been persisted to the database. This behaviour is required by some use cases where the overall logical transactions may span several different web pages and form submits (e.g. a complex account creation process with multiple screens, you wouldn't want the intermediate state of the beans to be persisted until the final confirmation).


                      As for your transactions they are being started and committed as per your bean declarations. But because flush mode is manual and no changes are being written to the database, there is nothing really to commit until the entity manager is flushed (i.e. it writes all the beans out) and then the transaction is committed for that request.


                      This can be confusing, but it is really a godsend in highly concurrent environments (and with version stamping) it can be made safe too.


                      Regards.

                      • 8. Re: Several transactions with manual flush
                        arshadm
                        • 9. Re: Several transactions with manual flush
                          vanyatka

                          Hi, Arshad, and thanks for the reply!


                          Flush mode has nothing to do with transactions per say.



                          It depends on the way you look at have something to do. Let's say you've got some transactional method which you run with manual flush. You cannot tell if this method failed or succeeded until you flush your changes to DB. And the status of this check can affect the logic of your application (e.g. either show the error to the user or workaround the problem somehow).


                          The whole request-response may have happenned and you may have made changes to several beans and saved them but that state has NOT been persisted to the database. This behaviour is required by some use cases where the overall logical transactions may span several different web pages and form submits (e.g. a complex account creation process with multiple screens, you wouldn't want the intermediate state of the beans to be persisted until the final confirmation).



                          I couldn't agree more. But we're talking about the use case where multiple transactions are involved.


                          As for your transactions they are being started and committed as per your bean declarations. But because flush mode is manual and no changes are being written to the database, there is nothing really to commit until the entity manager is flushed (i.e. it writes all the beans out) and then the transaction is committed for that request.



                          It seems that you think there can only be ONE single transaction per flush. When you call flush multiple DML statements are sent to DB mixed with multiple Transaction Demarcation Statements, such as begin and commit transaction. Flush can span several transaction boundaries, right?




                          • 10. Re: Several transactions with manual flush
                            joblini

                            BEGIN TRANSACTION
                            INSERT
                            DELETE
                            COMMIT
                            
                            BEGIN TRANSACTION
                            INSERT
                            DELETE
                            COMMIT
                            



                            No, only one transaction at a time.  Your example is incorrect.


                            • 11. Re: Several transactions with manual flush
                              joblini

                              Runtime exception will cause first transaction to rollback, the second transaction will not be started. 

                              • 12. Re: Several transactions with manual flush
                                arshadm

                                Yes, your understanding is quite right.


                                I was confusing beans in a detached state and manual flush mode. There will be an automatic flush on transaction commit anyway. Manual flush mode gives you some control over when you want beans to be persisted to the database within a request-response cycle.


                                Back to your original post about the two transactions. So you have two transactions and you want to know whether the second one will succeed if the first fails.


                                When the first transaction is commited, if there is an Exception and you don't handle it then probably it will never get to the second transactions. Manual flush mode won't affect this as the first commit will cause a transaparent flush anyway.


                                So, unless there was an exception and you didn't handle it. Your code will go on to the second transaction and perform those actions as anticipated.


                                Regards.