Package co.cask.cdap.data2.dataset2.tx

Source Code of co.cask.cdap.data2.dataset2.tx.Transactional

/*
* Copyright © 2014 Cask Data, Inc.
*
* 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 co.cask.cdap.data2.dataset2.tx;

import co.cask.tephra.TransactionAware;
import co.cask.tephra.TransactionExecutor;
import co.cask.tephra.TransactionExecutorFactory;
import co.cask.tephra.TransactionFailureException;
import com.google.common.base.Function;
import com.google.common.base.Predicates;
import com.google.common.base.Supplier;
import com.google.common.base.Throwables;
import com.google.common.collect.Iterables;

import java.io.Closeable;
import java.io.IOException;

/**
* Handy utility for performing transactional operations that delegates execution to {@link TransactionExecutor}
* and manages resources in transaction context. Transaction context is supplied using given {@link Supplier} and
* provides list of resources by implementing {@link Iterable}. This applies transaction logic to those resources
* that implement {@link TransactionAware}. Additionally, if resource implements {@link Closeable} its
* {@link java.io.Closeable#close()} is invoked at the end of transaction.
*
* @param <T> type of the transactional context
* @param <V> type of objects contained inside the transaction context
*/
public class Transactional<T extends Iterable<V>, V> {
  private final TransactionExecutorFactory txFactory;
  private final Supplier<T> supplier;

  public static <T extends Iterable<V>, V> Transactional<T, V> of(TransactionExecutorFactory txFactory,
                                                                            Supplier<T> supplier) {
    return new Transactional<T, V>(txFactory, supplier);
  }

  /**
   * Creates instance of {@link Transactional}.
   * @param txFactory factory for {@link TransactionExecutor}s
   * @param supplier supplies transaction context. Transaction logic will be applied to the items returned by the
   *                 context's getIterator() method for those that implement {@link TransactionAware}
   */
  private Transactional(TransactionExecutorFactory txFactory, Supplier<T> supplier) {
    this.txFactory = txFactory;
    this.supplier = supplier;
  }

  /**
   * Executes given function within new transaction.
   */
  public <R> R execute(final TransactionExecutor.Function<T, R> func)
    throws TransactionFailureException, InterruptedException, IOException {

    return execute(txFactory, supplier, func);
  }

  /**
   * Executes given function within new transaction and rethrows all exceptions with
   * {@link Throwables#propagate(Throwable)}
   */
  public <R> R executeUnchecked(final TransactionExecutor.Function<T, R> func) {
    try {
      return execute(txFactory, supplier, func);
    } catch (IOException e) {
      throw Throwables.propagate(e);
    } catch (TransactionFailureException e) {
      throw Throwables.propagate(e);
    } catch (InterruptedException e) {
      Thread.currentThread().interrupt();
      throw Throwables.propagate(e);
    }
  }

  /**
   * Executes function within new transaction. See {@link Transactional} for more details.
   * @param txFactory transaction factory to create new transaction
   * @param supplier supplier of transaction context
   * @param func function to execute
   * @param <V> type of object contained inside the transaction context
   * @param <T> type of the transaction context
   * @param <R> type of the function result
   * @return function result
   */
  public static <V, T extends Iterable<V>, R> R execute(TransactionExecutorFactory txFactory,
                                                        Supplier<T> supplier,
                                                        TransactionExecutor.Function<T, R> func)
    throws TransactionFailureException, IOException, InterruptedException {

    T it = supplier.get();
    Iterable<TransactionAware> txAwares = Iterables.transform(
      Iterables.filter(it, Predicates.instanceOf(TransactionAware.class)), new Function<V, TransactionAware>() {
      @Override
      public TransactionAware apply(V input) {
        return (TransactionAware) input;
      }
    });

    TransactionExecutor executor = txFactory.createExecutor(txAwares);
    try {
      return executor.execute(func, it);
    } finally {
      for (V t : it) {
        if (t instanceof Closeable) {
          ((Closeable) t).close();
        }
      }
    }
  }
}
TOP

Related Classes of co.cask.cdap.data2.dataset2.tx.Transactional

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.