Manually rollback JPA-Hibernate + Spring transaction
I am working with JPA 2 Hibernate and Spring MVC implementation for transaction management
I am using a generic DAO pattern to manage my database operations
We currently have a transaction that is a single method, for example: someDao.save (someObject) This is the @transactional method called from the JSF page The persistence method inherits from the Generic DAO, it is persisted in the database for many objects with oneToMany cascading relationships but there are several thousand insert statements to execute in the database, so it takes a very long time.
I would like to prompt the user to cancel the operation, but so far I cannot do that, when I call the save () method, it cannot be canceled until all inserts are done.
I tried to throw some exceptions to rollback the transaction from the nested PersistenceContext, but this is useless, it just ends up without error :(
Obviously I cannot throw an exception from the method, this is just one call from my source. JPA PersistenceContext does everything
Is there a way to undo the operation and force it to rollback?
source to share
Saving 1000 objects shouldn't take that long. Make sure you are using JDBC batching :
- You need to use an Entity ID that is not IDENTITY. IDENTIFICATION is disabled. The SEQUENCE and TABLE generators allow batch processing.
-
Set the following hibernation properties:
<property name="hibernate.order_updates" value="true"/> <property name="hibernate.order_inserts" value="true"/> <property name="hibernate.jdbc.batch_versioned_data" value="true"/> <property name="hibernate.jdbc.fetch_size" value="50"/> <property name="hibernate.jdbc.batch_size" value="520"/>
-
If you want to undo the save operation, you need to annotate your maintenance method with
-
For Spring
-
For Java EE
-
So after 30 seconds your save transaction will time out and an exception will be thrown, rolling back all your inserts.
Batch processing
If you want to undo the insert operation in a batch folder while allowing already processed items, you need to select batch processing.
You need to break all the items into pieces and insert them into bags. To do this, I would separate the start and end boundaries of the packet from the actual packet processing flow. Thus, while batch start and batch end are initiated by a web request, batch processing is performed by a dedicated ExecutorService .
This way you can:
- process packages simultaneously
- stop all batch processing at once using shutdownNow
Since query execution is I / O blocking operations, you need to support thread interrupts, so when a batch thread interrupts the batch executors, you can be notified to stop processing the next batch and exit as soon as possible.
I would use a separate ExecutionService
source to share
maybe this will help you:
http://docs.jboss.org/hibernate/orm/3.5/javadocs/org/hibernate/Session.html#cancelQuery ()
HibernateSession provides a cancelQuery method that you can use to cancel the current request.
Note. It may take a while before the request actually completes.
source to share