1/*-
2 * See the file LICENSE for redistribution information.
3 *
4 * Copyright (c) 2002,2008 Oracle.  All rights reserved.
5 *
6 * $Id: Transaction.java,v 12.9 2008/01/17 05:04:53 mjc Exp $
7 */
8
9package com.sleepycat.db;
10
11import com.sleepycat.db.internal.DbConstants;
12import com.sleepycat.db.internal.DbTxn;
13
14/**
15The Transaction object is the handle for a transaction.  Methods off the
16transaction handle are used to configure, abort and commit the
17transaction.  Transaction handles are provided to other Berkeley DB
18methods in order to transactionally protect those operations.
19<p>
20Transaction handles are not free-threaded; transactions handles may
21be used by multiple threads, but only serially, that is, the application
22must serialize access to the handle.  Once the
23{@link com.sleepycat.db.Transaction#abort Transaction.abort}, {@link com.sleepycat.db.Transaction#commit Transaction.commit} or
24{@link com.sleepycat.db.Transaction#discard Transaction.discard}
25methods are called, the handle may
26not be accessed again, regardless of the success or failure of the method.
27In addition, parent transactions may not issue any Berkeley DB operations
28while they have active child transactions (child transactions that have
29not yet been committed or aborted) except for {@link com.sleepycat.db.Environment#beginTransaction Environment.beginTransaction}, {@link com.sleepycat.db.Transaction#abort Transaction.abort} and {@link com.sleepycat.db.Transaction#commit Transaction.commit}.
30<p>
31To obtain a transaction with default attributes:
32<blockquote><pre>
33    Transaction txn = myEnvironment.beginTransaction(null, null);
34</pre></blockquote>
35To customize the attributes of a transaction:
36<blockquote><pre>
37    TransactionConfig config = new TransactionConfig();
38    config.setDirtyRead(true);
39    Transaction txn = myEnvironment.beginTransaction(null, config);
40</pre></blockquote>
41*/
42public class Transaction {
43    /*package */ final DbTxn txn;
44
45    Transaction(final DbTxn txn) {
46        this.txn = txn;
47    }
48
49    /**
50    Cause an abnormal termination of the transaction.
51    <p>
52    The log is played backward, and any necessary undo operations are done.
53    Before Transaction.abort returns, any locks held by the transaction will
54    have been released.
55    <p>
56    In the case of nested transactions, aborting a parent transaction
57    causes all children (unresolved or not) of the parent transaction
58    to be aborted.
59    <p>
60    All cursors opened within the transaction must be closed before the
61    transaction is aborted.
62    <p>
63    After Transaction.abort has been called, regardless of its return, the
64    {@link com.sleepycat.db.Transaction Transaction} handle may not be accessed again.
65    <p>
66    <p>
67@throws DatabaseException if a failure occurs.
68    */
69    public void abort()
70        throws DatabaseException {
71
72        txn.abort();
73    }
74
75    /**
76    End the transaction.  If the environment is configured for synchronous
77commit, the transaction will be committed synchronously to stable
78storage before the call returns.  This means the transaction will exhibit
79all of the ACID (atomicity, consistency, isolation, and durability)
80properties.
81<p>
82If the environment is not configured for synchronous commit, the commit
83will not necessarily have been committed to stable storage before the
84call returns.  This means the transaction will exhibit the ACI (atomicity,
85consistency, and isolation) properties, but not D (durability); that is,
86database integrity will be maintained, but it is possible this transaction
87may be undone during recovery.
88<p>
89In the case of nested transactions, if the transaction is a parent
90transaction, committing the parent transaction causes all unresolved
91children of the parent to be committed.  In the case of nested
92transactions, if the transaction is a child transaction, its locks are
93not released, but are acquired by its parent.  Although the commit of the
94child transaction will succeed, the actual resolution of the child
95transaction is postponed until the parent transaction is committed or
96aborted; that is, if its parent transaction commits, it will be
97committed; and if its parent transaction aborts, it will be aborted.
98<p>
99All cursors opened within the transaction must be closed before the
100transaction is committed.
101<p>
102After this method returns the {@link com.sleepycat.db.Transaction Transaction} handle may not be
103accessed again, regardless of the method's success or failure. If the
104method encounters an error, the transaction and all child transactions
105of the transaction will have been aborted when the call returns.
106<p>
107<p>
108@throws DatabaseException if a failure occurs.
109    */
110    public void commit()
111        throws DatabaseException {
112
113        txn.commit(0);
114    }
115
116    /**
117    End the transaction, committing synchronously.  This means the
118transaction will exhibit all of the ACID (atomicity, consistency,
119isolation, and durability) properties.
120<p>
121This behavior is the default for database environments unless otherwise
122configured using the {@link com.sleepycat.db.EnvironmentConfig#setTxnNoSync EnvironmentConfig.setTxnNoSync} method.  This
123behavior may also be set for a single transaction using the
124{@link com.sleepycat.db.Environment#beginTransaction Environment.beginTransaction} method.  Any value specified to
125this method overrides both of those settings.
126<p>
127In the case of nested transactions, if the transaction is a parent
128transaction, committing the parent transaction causes all unresolved
129children of the parent to be committed.  In the case of nested
130transactions, if the transaction is a child transaction, its locks are
131not released, but are acquired by its parent.  Although the commit of the
132child transaction will succeed, the actual resolution of the child
133transaction is postponed until the parent transaction is committed or
134aborted; that is, if its parent transaction commits, it will be
135committed; and if its parent transaction aborts, it will be aborted.
136<p>
137All cursors opened within the transaction must be closed before the
138transaction is committed.
139<p>
140After this method returns the {@link com.sleepycat.db.Transaction Transaction} handle may not be
141accessed again, regardless of the method's success or failure. If the
142method encounters an error, the transaction and all child transactions
143of the transaction will have been aborted when the call returns.
144<p>
145<p>
146@throws DatabaseException if a failure occurs.
147    */
148    public void commitSync()
149        throws DatabaseException {
150
151        txn.commit(DbConstants.DB_TXN_SYNC);
152    }
153
154    /**
155    End the transaction, not committing synchronously.
156This means the
157transaction will exhibit the ACI (atomicity, consistency, and isolation)
158properties, but not D (durability); that is, database integrity will be
159maintained, but it is possible this transaction may be undone during
160recovery.
161<p>
162This behavior may be set for a database environment using the
163{@link com.sleepycat.db.EnvironmentConfig#setTxnNoSync EnvironmentConfig.setTxnNoSync} method or for a single transaction
164using the {@link com.sleepycat.db.Environment#beginTransaction Environment.beginTransaction} method.  Any value
165specified to this method overrides both of those settings.
166<p>
167In the case of nested transactions, if the transaction is a parent
168transaction, committing the parent transaction causes all unresolved
169children of the parent to be committed.  In the case of nested
170transactions, if the transaction is a child transaction, its locks are
171not released, but are acquired by its parent.  Although the commit of the
172child transaction will succeed, the actual resolution of the child
173transaction is postponed until the parent transaction is committed or
174aborted; that is, if its parent transaction commits, it will be
175committed; and if its parent transaction aborts, it will be aborted.
176<p>
177All cursors opened within the transaction must be closed before the
178transaction is committed.
179<p>
180After this method returns the {@link com.sleepycat.db.Transaction Transaction} handle may not be
181accessed again, regardless of the method's success or failure. If the
182method encounters an error, the transaction and all child transactions
183of the transaction will have been aborted when the call returns.
184<p>
185<p>
186@throws DatabaseException if a failure occurs.
187    */
188    public void commitNoSync()
189        throws DatabaseException {
190
191        txn.commit(DbConstants.DB_TXN_NOSYNC);
192    }
193
194    /**
195    End the transaction, writing but not flushing the log.
196This means the
197transaction will exhibit the ACI (atomicity, consistency, and isolation)
198properties, but not D (durability); that is, database integrity will be
199maintained, but it is possible this transaction may be undone during
200recovery in the event that the operating system crashes. This option
201provides more durability than an asynchronous commit and has less
202performance cost than a synchronous commit.
203<p>
204This behavior may be set for a database environment using the
205{@link com.sleepycat.db.EnvironmentConfig#setTxnWriteNoSync EnvironmentConfig.setTxnWriteNoSync} method or for a single
206transaction using the {@link com.sleepycat.db.Environment#beginTransaction Environment.beginTransaction} method.
207Any value specified to this method overrides both of those settings.
208<p>
209In the case of nested transactions, if the transaction is a parent
210transaction, committing the parent transaction causes all unresolved
211children of the parent to be committed.  In the case of nested
212transactions, if the transaction is a child transaction, its locks are
213not released, but are acquired by its parent.  Although the commit of the
214child transaction will succeed, the actual resolution of the child
215transaction is postponed until the parent transaction is committed or
216aborted; that is, if its parent transaction commits, it will be
217committed; and if its parent transaction aborts, it will be aborted.
218<p>
219All cursors opened within the transaction must be closed before the
220transaction is committed.
221<p>
222After this method returns the {@link com.sleepycat.db.Transaction Transaction} handle may not be
223accessed again, regardless of the method's success or failure. If the
224method encounters an error, the transaction and all child transactions
225of the transaction will have been aborted when the call returns.
226<p>
227<p>
228@throws DatabaseException if a failure occurs.
229    */
230    public void commitWriteNoSync()
231        throws DatabaseException {
232
233        txn.commit(DbConstants.DB_TXN_WRITE_NOSYNC);
234    }
235
236    /**
237    Free up all the per-process resources associated with the specified
238    {@link com.sleepycat.db.Transaction Transaction} handle, neither committing nor aborting the
239    transaction.  This call may be used only after calls to
240    {@link com.sleepycat.db.Environment#recover Environment.recover} when there are multiple global
241    transaction managers recovering transactions in a single database
242    environment.  Any transactions returned by {@link com.sleepycat.db.Environment#recover Environment.recover} that are not handled by the current global transaction
243    manager should be discarded using this method.
244    <p>
245    The {@link com.sleepycat.db.Transaction Transaction} handle may not be accessed again after this
246    method has been called, regardless of the method's success or failure.
247    <p>
248    <p>
249@throws DatabaseException if a failure occurs.
250    */
251    public void discard()
252        throws DatabaseException {
253
254        txn.discard(0);
255    }
256
257    /**
258    Return the transaction's unique ID.
259        <p>
260    Locking calls made on behalf of this transaction should use the
261    value returned from this method as the locker parameter to the
262    {@link com.sleepycat.db.Environment#getLock Environment.getLock} or {@link com.sleepycat.db.Environment#lockVector Environment.lockVector}
263    calls.
264    <p>
265    @return
266    The transaction's unique ID.
267    <p>
268    <p>
269@throws DatabaseException if a failure occurs.
270    */
271    public int getId()
272        throws DatabaseException {
273
274        return txn.id();
275    }
276
277    /**
278    Get the user visible name for the transaction.
279    <p>
280    @return
281    The user visible name for the transaction.
282    <p>
283    */
284    public String getName()
285        throws DatabaseException {
286
287        return txn.get_name();
288    }
289
290    /**
291    Initiate the beginning of a two-phase commit.
292    <p>
293    In a distributed transaction environment, Berkeley DB can be used
294    as a local transaction manager.  In this case, the distributed
295    transaction manager must send <em>prepare</em> messages to each
296    local manager.  The local manager must then issue a
297    {@link com.sleepycat.db.Transaction#prepare Transaction.prepare} call and await its successful return
298    before responding to the distributed transaction manager.  Only
299    after the distributed transaction manager receives successful
300    responses from all of its <em>prepare</em> messages should it issue
301    any <em>commit</em> messages.
302    <p>
303    In the case of nested transactions, preparing the parent causes all
304    unresolved children of the parent transaction to be committed.
305    Child transactions should never be explicitly prepared.  Their fate
306    will be resolved along with their parent's during global recovery.
307    <p>
308    @param gid
309    The global transaction ID by which this transaction will be known.
310    This global transaction ID will be returned in calls to
311    {@link com.sleepycat.db.Environment#recover Environment.recover} method, telling the application which
312    global transactions must be resolved.  The gid parameter must be sized
313    at least DB_XIDDATASIZE (currently 128) bytes; only the first
314    DB_XIDDATASIZE bytes are used.
315    <p>
316    <p>
317@throws DatabaseException if a failure occurs.
318    */
319    public void prepare(final byte[] gid)
320        throws DatabaseException {
321
322        txn.prepare(gid);
323    }
324
325    /**
326    Set the user visible name for the transaction.
327    <p>
328    @param name
329    The user visible name for the transaction.
330    <p>
331    */
332    public void setName(final String name)
333        throws DatabaseException {
334
335        txn.set_name(name);
336    }
337
338    /**
339    Configure the timeout value for the transaction lifetime.
340    <p>
341    If the transaction runs longer than this time, the transaction may
342    may throw {@link com.sleepycat.db.DatabaseException DatabaseException}.
343    <p>
344    Timeouts are checked whenever a thread of control blocks on a lock
345    or when deadlock detection is performed.  For this reason, the
346    accuracy of the timeout depends on how often deadlock detection is
347    performed.
348    <p>
349    @param timeOut
350    The timeout value for the transaction lifetime, in microseconds.  As
351    the value is an unsigned 32-bit number of microseconds, the maximum
352    timeout is roughly 71 minutes.  A value of 0 disables timeouts for
353    the transaction.
354    <p>
355    This method may be called at any time during the life of the application.
356    <p>
357    <p>
358@throws DatabaseException if a failure occurs.
359    */
360    public void setTxnTimeout(final long timeOut)
361        throws DatabaseException {
362
363        txn.set_timeout(timeOut, DbConstants.DB_SET_TXN_TIMEOUT);
364    }
365
366    /**
367    Configure the lock request timeout value for the transaction.
368    <p>
369    If a lock request cannot be granted in this time, the transaction
370    may throw {@link com.sleepycat.db.DatabaseException DatabaseException}.
371    <p>
372    Timeouts are checked whenever a thread of control blocks on a lock
373    or when deadlock detection is performed.  For this reason, the
374    accuracy of the timeout depends on how often deadlock detection is
375    performed.
376    <p>
377    @param timeOut
378    The lock request timeout value for the transaction, in microseconds.
379    As the value is an unsigned 32-bit number of microseconds, the maximum
380    timeout is roughly 71 minutes.  A value of 0 disables timeouts for the
381    transaction.
382    <p>
383    This method may be called at any time during the life of the application.
384    <p>
385    <p>
386@throws DatabaseException if a failure occurs.
387    */
388    public void setLockTimeout(final long timeOut)
389        throws DatabaseException {
390
391        txn.set_timeout(timeOut, DbConstants.DB_SET_LOCK_TIMEOUT);
392    }
393}
394