/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you 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 net.jini.core.transaction; import net.jini.core.lease.Lease; import net.jini.core.lease.LeaseDeniedException; import java.rmi.RemoteException; /** * Interface for classes representing transactions returned by * <code>TransactionManager</code> servers for use with transaction * participants that implement the default transaction semantics. * The semantics: <p> * * The overall effect of executing a set of sibling pure transactions * concurrently is always equivalent to some sequential execution. <p> * * Ancestor transactions can execute concurrently with child transactions, * subject to the locking rules below. <p> * * Every transactional operation is described in terms of acquiring locks * on objects; these locks are held until the transaction completes. Whatever * the lock rules are, conflict rules are defined such that if two operations * do not commute, then they acquire conflicting locks. A transaction can * acquire a lock only if the conflicting locks are those held by ancestor * transactions (or itself). When a subtransaction commits, its locks are * inherited by the parent transaction. <p> * * If an object is defined to be created under a transaction, then the * existence of the object is only visible within that transaction and its * inferiors, but will disappear if the transaction aborts. If an object is * defined to be deleted under a transaction, then the object is not visible * to any transaction (including the deleting transaction) but will reappear * if the transaction aborts. When a nested transaction commits, visibility * state is inherited by the parent transaction. <p> * * Once a transaction reaches the <code>VOTING</code> stage, if all * execution under the transaction (and its subtransactions) has finished, * then the only reasons the transaction can abort are: the manager crashes * (or has crashed); one or more participants crash (or have crashed); or * an explicit abort. <p> * * Transaction deadlocks are not guaranteed to be prevented or even detected, * but managers and participants are permitted to break known deadlocks by * aborting transactions. <p> * * An orphan transaction (it or one of its ancestors is guaranteed to abort) * is not guaranteed to be detected. <p> * * Causal ordering information about transactions is not guaranteed to be * propagated. <p> * * As long as a transaction persists in attempting to acquire a lock that * conflicts with another transaction, the participant will persist in * attempting to resolve the outcome of the transaction that holds the * conflicting lock. * * @author Sun Microsystems, Inc. * * @see NestableTransaction * @see net.jini.core.transaction.server.TransactionManager * @see net.jini.core.transaction.server.NestableTransactionManager * @see TransactionFactory * * @since 1.0 */ public interface Transaction { /** Class that holds return values from create methods. */ public static class Created implements java.io.Serializable { static final long serialVersionUID = -5199291723008952986L; /** * The transaction. * @serial */ public final Transaction transaction; /** * The lease. * @serial */ public final Lease lease; /** * Simple constructor. * * @param transaction the transaction created * @param lease the lease granted */ public Created(Transaction transaction, Lease lease) { this.transaction = transaction; this.lease = lease; } // inherit javadoc public String toString() { return this.getClass().getName() + "[lease=" + lease + ", transaction=" + transaction + "]"; } } /** * Commit the transaction. Commit asks the transaction manager to * execute the voting process with the participants. Returns if the * transaction successfully reaches either the <code>NOTCHANGED</code> * or the <code>COMMITTED</code> state, without waiting for the * transaction manager to notify all participants of the decision. * If the transaction must be aborted (because one or more participants * are unable to prepare), <code>CannotCommitException</code> is thrown * without waiting for the transaction manager to notify all participants * of the decision. * * @throws UnknownTransactionException if the transaction is unknown * to the manager. This may be because the transaction ID was * incorrect, or because the transaction has proceeded to * cleanup due to an earlier commit or abort, and has been * forgotten. * @throws CannotCommitException if the transaction reaches the ABORTED * state, or is known to have previously reached that state due * to an earlier commit or abort. * @throws RemoteException if a communication error occurs. */ void commit() throws UnknownTransactionException, CannotCommitException, RemoteException; /** * Commit the transaction, waiting for participants to be notified of * the decision. Commit asks the transaction manager to execute the * voting process with the participants. Returns if the transaction * successfully reaches either the <code>NOTCHANGED</code> or the * <code>COMMITTED</code> state, and the transaction manager has * notified all participants of the decision, before the specified * timeout expires. If the transaction must be aborted (because one * or more participants are unable to prepare), * <code>CannotCommitException</code> is thrown if the transaction * manager is able to notify all participants of the decision before * the specified timeout expires. If the transaction manager reaches * a decision, but is unable to notify all participants of that * decision before the specified timeout expires, then * <code>TimeoutExpiredException</code> is thrown. If the specified * timeout expires before the transaction manager reaches a decision, * <code>TimeoutExpiredException</code> is not thrown until the * manager reaches a decision. * * @param waitFor timeout to wait, from the start of the call until * all participants have been notified of the transaction manager's * decision * * @throws UnknownTransactionException if the transaction is unknown * to the manager. This may be because the transaction ID was * incorrect, or because the transaction has proceeded to * cleanup due to an earlier commit or abort, and has been * forgotten. * @throws CannotCommitException if the transaction reaches the ABORTED * state, or is known to have previously reached that state due * to an earlier commit or abort. * @throws TimeoutExpiredException if the timeout expires before all * participants have been notified. * @throws RemoteException if a communication error occurs. */ void commit(long waitFor) throws UnknownTransactionException, CannotCommitException, TimeoutExpiredException, RemoteException; /** * Abort the transaction. This can be called at any time by * any object holding a reference to the transaction. Abort asks * the transaction manager to abort the transaction and to notify * each participant of the decision, resulting in them rolling back * any state changes made as part of the transaction. Returns as * soon as the transaction manager records the abort decision, without * waiting for the transaction manager to notify all participants of * the decision. * * @throws UnknownTransactionException if the transaction is unknown * to the manager. This may be because the transaction ID was * incorrect, or because the transaction has proceeded to * cleanup due to an earlier commit or abort, and has been * forgotten. * @throws CannotAbortException if the transaction is known to have * previously reached the COMMITTED state due to an earlier * commit. * @throws RemoteException if a communication error occurs. */ void abort() throws UnknownTransactionException, CannotAbortException, RemoteException; /** * Abort the transaction, waiting for participants to be notified of * the decision. This can be called at any time by any object holding * a reference to the transaction. Abort asks the transaction manager * to abort the transaction and to notify each participant of the * decision, resulting in them rolling back any state changes made as * part of the transaction. Returns if the transaction manager records * the decision and is able to notify all participants of the decision * before the specified timeout expires. If the transaction manager * is unable to notify all participants of the decision before the * specified timeout expires, then <code>TimeoutExpiredException</code> * is thrown. * * @param waitFor timeout to wait, from the start of the call until * all participants have been notified of the transaction manager's * decision. * * @throws UnknownTransactionException if the transaction is unknown * to the manager. This may be because the transaction ID was * incorrect, or because the transaction has proceeded to * cleanup due to an earlier commit or abort, and has been * forgotten. * @throws CannotAbortException if the transaction is known to have * previously reached the COMMITTED state due to an earlier * commit. * @throws TimeoutExpiredException if the timeout expires before all * participants have been notified. * @throws RemoteException if a communication error occurs. */ void abort(long waitFor) throws UnknownTransactionException, CannotAbortException, TimeoutExpiredException, RemoteException; }