Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * Copyright (c) 2010-2011. Axon Framework
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *     http://www.apache.org/licenses/LICENSE-2.0
   *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
 
 package org.axonframework.unitofwork;
 
 
 import java.util.List;
 import java.util.Set;

Abstract implementation of the UnitOfWork interface. Provides the necessary implementations to support most actions required by any Unit of Work, such as managing registration with the CurrentUnitOfWork and support for nesting a Unit of Work.

Author(s):
Allard Buijze
Since:
0.7
See also:
CurrentUnitOfWork
 
 public abstract class AbstractUnitOfWork implements UnitOfWork {
 
     private static final Logger logger = LoggerFactory.getLogger(AbstractUnitOfWork.class);
 
     private boolean isStarted;
     private UnitOfWork outerUnitOfWork;
 
     @Override
     public void commit() {
         .debug("Committing Unit Of Work");
         assertStarted();
         try {
             notifyListenersPrepareCommit();
             saveAggregates();
             if ( == null) {
                 .debug("This Unit Of Work is not nested. Finalizing commit...");
                 doCommit();
                 stop();
                 performCleanup();
             } else if (.isDebugEnabled()) {
                 .debug("This Unit Of Work is nested. Commit will be finalized by outer Unit Of Work.");
             }
         } catch (RuntimeException e) {
             .debug("An error occurred while committing this UnitOfWork. Performing rollback...");
             doRollback(e);
             stop();
             if ( == null) {
                 performCleanup();
             }
             throw e;
         } finally {
             .debug("Clearing resources of this Unit Of Work.");
             clear();
         }
     }
 
     private void performCleanup() {
         for (AbstractUnitOfWork uow : ) {
             uow.performCleanup();
         }
         notifyListenersCleanup();
     }

    
Send a UnitOfWorkListener.onCleanup() notification to all registered listeners. The implementation must ensure that all listeners are notified, even if one throws an exception.
 
     protected abstract void notifyListenersCleanup();

    
Send a UnitOfWorkListener.onRollback(java.lang.Throwable) notification to all registered listeners.

Parameters:
cause The cause of the rollback
 
     protected abstract void notifyListenersRollback(Throwable cause);
 
     @Override
     public void rollback() {
         rollback(null);
     }
 
     @Override
    public void rollback(Throwable cause) {
        if (cause != null && .isInfoEnabled()) {
            .debug("Rollback requested for Unit Of Work due to exception. "cause);
        } else if (.isInfoEnabled()) {
            .debug("Rollback requested for Unit Of Work for unknown reason.");
        }
        try {
            if (isStarted()) {
                for (AbstractUnitOfWork inner : ) {
                    CurrentUnitOfWork.set(inner);
                    inner.rollback(cause);
                }
                doRollback(cause);
            }
        } finally {
            if ( == null) {
                performCleanup();
            }
            clear();
            stop();
        }
    }
    @Override
    public void start() {
        .debug("Starting Unit Of Work.");
        if () {
            throw new IllegalStateException("UnitOfWork is already started");
        } else if (CurrentUnitOfWork.isStarted()) {
            // we're nesting.
            this. = CurrentUnitOfWork.get();
            if ( instanceof AbstractUnitOfWork) {
                ((AbstractUnitOfWork).registerInnerUnitOfWork(this);
            } else {
                .registerListener(new CommitOnOuterCommitTask());
            }
        }
        .debug("Registering Unit Of Work as CurrentUnitOfWork");
        CurrentUnitOfWork.set(this);
         = true;
        doStart();
    }
    @Override
    public boolean isStarted() {
        return ;
    }
    private void stop() {
        .debug("Stopping Unit Of Work");
         = false;
    }

    
Performs logic required when starting this UnitOfWork instance.

This implementation does nothing and may be freely overridden.

    protected void doStart() {
    }

    
Executes the logic required to commit this unit of work.
    protected abstract void doCommit();

    
Executes the logic required to commit this unit of work.

Parameters:
cause the cause of the rollback
    protected abstract void doRollback(Throwable cause);
    private void performInnerCommit() {
        .debug("Finalizing commit of inner Unit Of Work...");
        CurrentUnitOfWork.set(this);
        try {
            doCommit();
        } catch (RuntimeException t) {
            doRollback(t);
            throw t;
        } finally {
            clear();
            stop();
        }
    }
    private void assertStarted() {
        if (!) {
            throw new IllegalStateException("UnitOfWork is not started");
        }
    }
    private void clear() {
        CurrentUnitOfWork.clear(this);
    }

    
Commit all registered inner units of work. This should be invoked after events have been dispatched and before any listeners are notified of the commit.
    protected void commitInnerUnitOfWork() {
        for (AbstractUnitOfWork unitOfWork : ) {
            if (unitOfWork.isStarted()) {
                unitOfWork.performInnerCommit();
            }
        }
    }
    private void registerInnerUnitOfWork(AbstractUnitOfWork unitOfWork) {
        .add(unitOfWork);
    }

    
Saves all registered aggregates by calling their respective callbacks.
    protected abstract void saveAggregates();

    
Send a UnitOfWorkListener.onPrepareCommit(java.util.Set,java.util.List) notification to all registered listeners.
    protected abstract void notifyListenersPrepareCommit();
    private class CommitOnOuterCommitTask implements UnitOfWorkListener {
        @Override
        public void afterCommit() {
            performInnerCommit();
        }
        @Override
        public void onRollback(Throwable failureCause) {
            CurrentUnitOfWork.set(AbstractUnitOfWork.this);
            try {
                doRollback(failureCause);
            } finally {
                CurrentUnitOfWork.clear(AbstractUnitOfWork.this);
            }
        }
        @Override
        public void onPrepareCommit(Set<AggregateRootaggregateRootsList<Eventevents) {
        }
        @Override
        public void onCleanup() {
            performCleanup();
        }
    }
New to GrepCode? Check out our FAQ X