I have a requirement of executing parent task which may or maynot have child task. Each parent and child task should be run in thread. If something goes wrong in parent or child execution the transaction of both parent and child task must be rollback. I am using hibernate4.
2 Answers
If I got it, the parent and the child task will run in differents threads.
According to me it's a very bad idea that does not worth considering.
While it may be possible using jta transaction, it's clearly not the case using hibernate transaction management delegation to underlying jdbc connection (you have one connection per session and MUST NOT share an hibernate session between threads).
Using jta you will have to handle connection retrieval and transactions yourself and can't so take advantages of connection pooling and container managed transaction (spring or java ee ones). It may be overcomplicated for about no performance improvments as sharing the database connection between two threads will just probably move the bottleneck one level below.
-
well so it's very simple (just make both tasks part of the same transaction) and I don't get what the question is – Gab Jun 22 '15 at 15:20
-
I just want to know how to do it It will be great if you can share some suedo code – Mohsin Khan Jun 22 '15 at 15:49
-
It really depends on your context. Are you running in some spring or jee container or is it a standalone application ? Do you want to use jta transaction or just jdbc ones ? – Gab Jun 22 '15 at 16:11
-
its a standalone application and i want to use hibernate4 – Mohsin Khan Jun 22 '15 at 16:30
-
Also I am able to create two thread for two parent task both has common insert method on same table but when I am running the app. The app goes in the method and then nothing happens – Mohsin Khan Jun 22 '15 at 16:32
According to OP expectation here is a pseudo code for Hibernate 4 standalone session management with jdbc transaction (I personnaly advise to go with a container (Java ee or spring) and JTA container managed transaction)
In hibernate.cfg.xml
<property name="hibernate.current_session_context_class">thread</property>
SessionFactory :
Configuration configuration = new Configuration();
configuration.configure("hibernate.cfg.xml");
StandardServiceRegistryBuilder builder = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties());
SessionFactory sessionFactory = configuration.buildSessionFactory(builder.build());
The session factory should be exposed using a singleton (any way you choose you must have only one instance for the whole app)
public void executeParentTask() {
try {
sessionFactory.getCurrentSession().beginTransaction();
sessionFactory.getCurrentSession().persist(someEntity);
myChildTask.execute();
sessionFactory.getCurrentSession().getTransaction().commit();
}
catch (RuntimeException e) {
sessionFactory .getCurrentSession().getTransaction().rollback();
throw e; // or display error message
}
}
getCurrentSession()
will return the session bound to the current thread. If you manage the thread execution yourself you should create the session at the beginning of the thread execution and close it at the end.
the child task will retrieve the same session than the parent one using sessionFactory.getCurrentSession()
See https://docs.jboss.org/hibernate/orm/4.3/manual/en-US/html/ch03.html#configuration-sessionfactory
You may find this interesting too : How to configure and get session in Hibernate 4.3.4.Final?
-
Hi I am using ApplicationContect.xml which is having session factory bean defined. How can I configure the configuration object for building StandardServiceRegistryBuilder .I dont have hibernate.cfg.xml – Mohsin Khan Jun 23 '15 at 18:22
-
... didn't i asked if you were running in some spring or java ee container ? – Gab Jun 24 '15 at 07:17
-
I am running on Spring container . But we are using Hibernate transaction manager. – Mohsin Khan Jun 24 '15 at 13:37
-
It's not a problem, then just go with Spring transaction annotation with requiered propagation. Don't expect a code example from me, next time try to explicit the question a bit more (context, etc...) – Gab Jun 24 '15 at 14:01
-
I am sorry to bug you. Just one last question considering th parent child task Scenario. Will Spring be able to handle the transaction rollback for thread running parent and child task. – Mohsin Khan Jun 24 '15 at 14:06
-
Yes. See http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/transaction/annotation/Propagation.html. If parent task is transactional so will be the child task (it will be part of the same tx) unless its propagation level is not_supported or requieres_new – Gab Jun 24 '15 at 14:11
-
The problem I am facing now. Is I have the DAO method which is doing insert into a table. Which is run by the Child task1 executor. However I marked that method as Transactional but when my child Task2 executor fails it didnt rollback the insert operation of child task1. – Mohsin Khan Jun 24 '15 at 15:16
-
the session context may be misconfigured. did you let the line `
thread ` inhibernate cfg ? this is for hibernate in standalone mode which is not your case as you couple it with spring. get a proper tutorial on spring and hibernate integration and follow it. – Gab Jun 24 '15 at 15:57 -
Hi, It is doing the rollback for the first transaction. Though it is showing rollback in the logs for all the thread. It is actually doing rollback for first thread. rest of the thread data get inserted even if there is failure. – Mohsin Khan Jun 25 '15 at 16:39