/
Transaction.java
267 lines (254 loc) · 11.7 KB
/
Transaction.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
/*
* 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 java.io.IOException;
import java.rmi.RemoteException;
import net.jini.core.lease.Lease;
import org.apache.river.api.io.AtomicSerial;
import org.apache.river.api.io.AtomicSerial.GetArg;
import org.apache.river.api.io.AtomicSerial.PutArg;
import org.apache.river.api.io.AtomicSerial.SerialForm;
/**
* 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. */
@AtomicSerial
public static class Created implements java.io.Serializable {
static final long serialVersionUID = -5199291723008952986L;
public static SerialForm[] serialForm(){
return new SerialForm[]{
new SerialForm("transaction", Transaction.class),
new SerialForm("lease", Lease.class)
};
}
public static void serialize(PutArg arg, Created t) throws IOException{
arg.put("transaction", t.transaction);
arg.put("lease", t.lease);
arg.writeArgs();
}
/**
* 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;
}
/**
* AtomicSerial constructor.
*
* @param arg atomic deserialization parameter
* @throws IOException if there are I/O errors while reading from GetArg's
* underlying <code>InputStream</code>
*/
public Created(GetArg arg) throws IOException, ClassNotFoundException{
this(arg.get("transaction", null, Transaction.class),
arg.get("lease", null, Lease.class));
}
// 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;
}