Announcement Announcement Module
No announcement yet.
How to do standalone session inside an existing transaction? Page Title Module
Move Remove Collapse
Conversation Detail Module
  • Filter
  • Time
  • Show
Clear All
new posts

  • How to do standalone session inside an existing transaction?


    I'm new to Spring/Hibernate, yet managed to use it very fast, however I encountered the following problem.

    I'm writing a plugin inside an application that already use Hibernate+Spring. My plugin seems to be executing inside a spring/hibernate transaction, but my plugin is not interested in being part of that transaction. My plugin even access a different DB.

    My plugin code loads classes with data from the DB, then format the loaded objects in memory some more and then display them. Nothing more than that. The formatting must not go back to the DB.

    However, I see that after my code is done, the changes I do in memory are written back to the DB. Seems this is due to the external transaction that was alreay open.

    I use the simplest usage of HibernateTemplate for DAO, LocalSessionFactoryBean & the DAO beans declared in the Context.xml.

    I couldn't find how to get my code to run independently of the global transaction which is not under my control, or how to prevent my changes from going back to the DB any other way (other than not doing the memory manipulation inside the hibernated classes). When I debugged the code it seemed to me I can't control that.

    Can anyone help?

    Thanks in advance.

  • #2
    You should be using a different SessionFactory and DataSource for the plugin, and will not have interference with the main app...


    • #3
      This is how I did it.

      Still, when debugging I see that it checks for a transaction per thread, and then later it seem to save the modified objects back to the DB outside my code.


      • #4
        Your Hibernate Session will by default indeed automatically register with the global transaction, no matter which SessionFactory created it.

        To make your code execute outside of that transaction, put a TransactionProxyFactoryBean (or TransactionTemplate) at its entry point, specifying PROPAGATION_NOT_SUPPORTED (which will suspend the existing transaction, if any, and execute your code non-transactionally).

        The above will in principle work with any transaction strategy. However, in the case of JTA, the JTA TransactionManager needs to be available (not just the UserTransaction). This might involve specific setup, depending on your J2EE server (see JtaTransactionManager's javadoc for details).

        Alternatively, don't format your objects within their persistent instances, but rather copy them and format that copy, or keep the formatted fields in different member variables of the original instances. This won't cause any side effects for their persistent state, even within a transaction.



        • #5
          Sorry, for some reason I was assuming your plugin was executing in a separate thread, although you didn't say that. Juergen is correct that you need to suspend any existing transactions, by using propagation_not_supported.


          • #6
            Why not specify PROPAGATION_REQUIRES_NEW?

            The plugin may be issuing more than one SELECT to the database, and the original poster did not specifiy if other external processes were updating his (plugin) database...

            What's the benefit of non-transactional execution?