![JAR search and dependency download from the Maven repository](/logo.png)
com.yahoo.elide.datastores.multiplex.MultiplexTransaction Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of elide-datastore-multiplex Show documentation
Show all versions of elide-datastore-multiplex Show documentation
Elide entity manager for multiple data store support
The newest version!
/*
* Copyright 2016, Yahoo Inc.
* Licensed under the Apache License, Version 2.0
* See LICENSE file in project root for terms.
*/
package com.yahoo.elide.datastores.multiplex;
import com.yahoo.elide.core.RequestScope;
import com.yahoo.elide.core.datastore.DataStore;
import com.yahoo.elide.core.datastore.DataStoreIterable;
import com.yahoo.elide.core.datastore.DataStoreTransaction;
import com.yahoo.elide.core.dictionary.EntityDictionary;
import com.yahoo.elide.core.exceptions.InvalidCollectionException;
import com.yahoo.elide.core.filter.Operator;
import com.yahoo.elide.core.filter.expression.FilterExpression;
import com.yahoo.elide.core.filter.expression.PredicateExtractionVisitor;
import com.yahoo.elide.core.filter.predicates.FilterPredicate;
import com.yahoo.elide.core.request.Attribute;
import com.yahoo.elide.core.request.EntityProjection;
import com.yahoo.elide.core.request.Relationship;
import com.yahoo.elide.core.type.ClassType;
import com.yahoo.elide.core.type.Type;
import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.ListIterator;
import java.util.Set;
import java.util.function.Consumer;
/**
* Multiplex transaction handler. Process each sub-database transactions within a single transaction.
* If any commit fails in process, reverse any commits already completed.
*/
public abstract class MultiplexTransaction implements DataStoreTransaction {
protected LinkedHashMap transactions;
protected final MultiplexManager multiplexManager;
/**
* Multiplex transaction handler.
* @param multiplexManager associated manager
*/
public MultiplexTransaction(MultiplexManager multiplexManager) {
this.multiplexManager = multiplexManager;
this.transactions = new LinkedHashMap<>(multiplexManager.dataStores.size());
}
protected abstract DataStoreTransaction beginTransaction(DataStore dataStore);
@Override
public void createObject(T entity, RequestScope scope) {
getTransaction(EntityDictionary.getType(entity)).createObject(entity, scope);
}
@Override
public T loadObject(EntityProjection projection,
Serializable id,
RequestScope scope) {
return getTransaction(projection.getType()).loadObject(projection, id, scope);
}
@Override
public DataStoreIterable loadObjects(
EntityProjection projection,
RequestScope scope) {
return getTransaction(projection.getType()).loadObjects(projection, scope);
}
@Override
public void flush(RequestScope scope) {
processTransactions(dataStoreTransaction -> dataStoreTransaction.flush(scope));
}
@Override
public void preCommit(RequestScope scope) {
processTransactions(dataStoreTransaction -> dataStoreTransaction.preCommit(scope));
}
@Override
public void commit(RequestScope scope) {
// flush all before commit
flush(scope);
processTransactions(dataStoreTransaction -> dataStoreTransaction.commit(scope));
}
/**
* Processes the transactions in reverse order and is non null.
*
* @param processor process the transaction
*/
protected void processTransactions(Consumer processor) {
// Transactions must be processed in reverse order
ListIterator iterator = new ArrayList<>(transactions.values())
.listIterator(transactions.size());
while (iterator.hasPrevious()) {
DataStoreTransaction dataStoreTransaction = iterator.previous();
if (dataStoreTransaction != null) {
processor.accept(dataStoreTransaction);
}
}
}
@Override
public void close() throws IOException {
IOException cause = null;
// Transactions must be processed in reverse order
ListIterator iterator = new ArrayList<>(transactions.values())
.listIterator(transactions.size());
while (iterator.hasPrevious()) {
DataStoreTransaction dataStoreTransaction = iterator.previous();
if (dataStoreTransaction != null) {
try {
dataStoreTransaction.close();
} catch (IOException | Error | RuntimeException e) {
if (cause != null) {
cause.addSuppressed(e);
} else if (e instanceof IOException ioException) {
cause = ioException;
} else {
cause = new IOException(e);
}
}
}
}
transactions.clear();
if (cause != null) {
throw cause;
}
}
protected DataStoreTransaction getTransaction(Object object) {
return getTransaction(ClassType.of(object.getClass()));
}
protected DataStoreTransaction getTransaction(Type> cls) {
DataStore lookupDataStore = this.multiplexManager.getSubManager(cls);
DataStoreTransaction transaction = transactions.get(lookupDataStore);
if (transaction == null) {
for (DataStore dataStore : multiplexManager.dataStores) {
if (dataStore.equals(lookupDataStore)) {
transaction = beginTransaction(dataStore);
transactions.put(dataStore, transaction);
break;
}
}
if (transaction == null) {
throw new InvalidCollectionException(cls.getName());
}
}
return transaction;
}
protected DataStoreTransaction getRelationTransaction(Object object, String relationName) {
EntityDictionary dictionary = multiplexManager.getDictionary();
Type> relationClass = dictionary.getParameterizedType(EntityDictionary.getType(object), relationName);
return getTransaction(relationClass);
}
@Override
public DataStoreIterable getToManyRelation(
DataStoreTransaction tx,
T entity,
Relationship relation,
RequestScope scope
) {
DataStoreTransaction relationTx = getRelationTransaction(entity, relation.getName());
Type
© 2015 - 2025 Weber Informatics LLC | Privacy Policy