This content has been marked as final.
Show 16 replies
-
15. Re: Transactional on private method
mroeoesli Aug 28, 2009 11:41 AM (in response to asookazian)I made a class simular to the work class but it makes a litle bit more.
It proofs if there is a transaction and if there is a transaction it will join to it. If there is no transaction it will create one.
The transactions which are created by my class will be commited by my class.I don't know if my way is a good way but it works for me :)
What do you think about my way? Is that a good way or do you see some prolems if I do transaction handling like this?
my Class
public abstract class RunAsJoinedTransaction implements Synchronization { private static final LogProvider log = Logging.getLogProvider(RunAsJoinedTransaction.class); private Session session; private boolean resetFlushMode = false; @SuppressWarnings("unused") private boolean synchronizationRegistered = false; private boolean newTransactionCreated = false; public RunAsJoinedTransaction(Session session) { if (session != null) { this.session = session; } else { throw new RuntimeException("no valid session"); } } public RunAsJoinedTransaction(EntityManager entityManager) { if (entityManager.getDelegate() != null) { this.session = (Session) entityManager.getDelegate(); } else { throw new RuntimeException("no valid session"); } } public RunAsJoinedTransaction(Session session, boolean resetFlushMode) { this(session); this.resetFlushMode = resetFlushMode; } public RunAsJoinedTransaction(EntityManager entityManager, boolean resetFlushMode) { this(entityManager); this.resetFlushMode = resetFlushMode; } public abstract void execute(); public void run() { try { joinTransaction(); } catch (SystemException e) { throw new RuntimeException("join transaction failed " + e.toString()); } catch (NotSupportedException e) { throw new RuntimeException("join transaction failed " + e.toString()); } FlushMode oldMode = session.getFlushMode(); if (resetFlushMode == true) { session.setFlushMode(FlushMode.MANUAL); } execute(); if (resetFlushMode == true) { session.setFlushMode(oldMode); } try { commit(); } catch (Exception e) { throw new RuntimeException("commit transaction failed " + e.toString()); } } private void joinTransaction() throws SystemException, NotSupportedException { UserTransaction transaction = Transaction.instance(); if (transaction.isActive()) { session.isOpen(); try { transaction.registerSynchronization(this); } catch (Exception e) { session.getTransaction().registerSynchronization(this); } synchronizationRegistered = true; newTransactionCreated = false; } else { // new transaction required transaction.begin(); newTransactionCreated = true; } } private void commit() throws Exception { if (newTransactionCreated == true) { UserTransaction transaction = Transaction.instance(); try { if (transaction.isMarkedRollback()) { log.debug("rolling back transaction"); transaction.rollback(); } else { log.debug("committing transaction"); transaction.commit(); } } catch (Exception e) { if (transaction.getStatus() != Status.STATUS_NO_TRANSACTION && isRollbackRequired(e, true)) { log.debug("rolling back transaction"); transaction.rollback(); } throw e; } } } public static boolean isRollbackRequired(Exception e, boolean isJavaBean) { Class<? extends Exception> clazz = e.getClass(); return (isSystemException(e, isJavaBean, clazz)) || (isJavaBean && clazz.isAnnotationPresent(APPLICATION_EXCEPTION) && rollback(clazz.getAnnotation(APPLICATION_EXCEPTION))) || (clazz.isAnnotationPresent(ApplicationException.class) && clazz.getAnnotation(ApplicationException.class).rollback()); } private static boolean isSystemException(Exception e, boolean isJavaBean, Class<? extends Exception> clazz) { return isJavaBean && (e instanceof RuntimeException) && !clazz.isAnnotationPresent(APPLICATION_EXCEPTION) && !clazz.isAnnotationPresent(ApplicationException.class) && !JSF.VALIDATOR_EXCEPTION.isInstance(e) && !JSF.CONVERTER_EXCEPTION.isInstance(e); } public void afterCompletion(int arg0) { synchronizationRegistered = false; } }
here is an example how you can use it.
new RunAsJoinedTransaction(mySession/myEntityManager) { public void execute() { //doSomething } }.run();
maybe that can help you.
Greetz Marco
-
16. Re: Transactional on private method
asookazian Aug 28, 2009 7:07 PM (in response to asookazian)Thanks but I seem to have solved it (although perhaps not an optimal solution to the tx management requirement):