1 2 Previous Next 16 Replies Latest reply on Aug 28, 2009 7:07 PM by asookazian Go to original post
      • 15. Re: Transactional on private method

        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

          Thanks but I seem to have solved it (although perhaps not an optimal solution to the tx management requirement):


          http://www.seamframework.org/Community/UsageOfUTTransaction

          1 2 Previous Next