*/
package org.opendaylight.controller.cluster.datastore;
+import static com.google.common.base.Preconditions.checkState;
+import static java.util.Objects.requireNonNull;
+
import com.google.common.base.MoreObjects;
-import com.google.common.base.Preconditions;
-import javax.annotation.concurrent.NotThreadSafe;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeSnapshot;
+import org.opendaylight.controller.cluster.access.concepts.TransactionIdentifier;
+import org.opendaylight.controller.cluster.datastore.persisted.AbortTransactionPayload;
+import org.opendaylight.yangtools.concepts.Identifiable;
+import org.opendaylight.yangtools.yang.data.tree.api.DataTreeSnapshot;
/**
- * Abstract base for transactions running on SharrdDataTree.
+ * Abstract base for transactions running on SharrdDataTree. This class is NOT thread-safe.
*
* @param <T> Backing transaction type.
*/
-@NotThreadSafe
-abstract class AbstractShardDataTreeTransaction<T extends DataTreeSnapshot> {
+abstract class AbstractShardDataTreeTransaction<T extends DataTreeSnapshot>
+ implements Identifiable<TransactionIdentifier> {
+ private final ShardDataTreeTransactionParent parent;
+ private final TransactionIdentifier id;
private final T snapshot;
- private final String id;
+
private boolean closed;
- protected AbstractShardDataTreeTransaction(final String id, final T snapshot) {
- this.snapshot = Preconditions.checkNotNull(snapshot);
- this.id = Preconditions.checkNotNull(id);
+ AbstractShardDataTreeTransaction(final ShardDataTreeTransactionParent parent, final TransactionIdentifier id,
+ final T snapshot) {
+ this.parent = requireNonNull(parent);
+ this.snapshot = requireNonNull(snapshot);
+ this.id = requireNonNull(id);
+ }
+
+ @Override
+ public final TransactionIdentifier getIdentifier() {
+ return id;
+ }
+
+ final ShardDataTreeTransactionParent getParent() {
+ return parent;
}
final T getSnapshot() {
return true;
}
+ final void abort(final Runnable callback) {
+ checkState(close(), "Transaction is already closed");
+ parent.abortTransaction(this, callback);
+ }
+
+ /**
+ * This method is exposed for sake of {@link ShardTransaction}, which is an actor. We need to ensure that
+ * the parent is updated to reflect the transaction has been closed, but no journal actions may be invoked.
+ *
+ * <p>
+ * ShardTransaction is responsible for additionally sending a request to persist an {@link AbortTransactionPayload}
+ * via a message to the Shard actor.
+ */
+ final void abortFromTransactionActor() {
+ if (close()) {
+ parent.abortFromTransactionActor(this);
+ }
+ }
+
@Override
public final String toString() {
- return MoreObjects.toStringHelper(this).add("id", id).add("closed", closed).add("snapshot", snapshot).toString();
+ return MoreObjects.toStringHelper(this).add("id", id).add("closed", closed).add("snapshot", snapshot)
+ .toString();
}
-
- abstract void abort();
}