1 /*-
2  * Copyright (c) 2002, 2020 Oracle and/or its affiliates.  All rights reserved.
3  *
4  * See the file LICENSE for license information.
5  *
6  * $Id$
7  */
8 
9 package com.sleepycat.db;
10 
11 import com.sleepycat.db.internal.DbConstants;
12 import com.sleepycat.db.internal.DbEnv;
13 import com.sleepycat.db.internal.DbTxn;
14 
15 /**
16 Specifies the attributes of a database environment transaction.
17 */
18 public class TransactionConfig implements Cloneable {
19     /*
20      * For internal use, to allow null as a valid value for
21      * the config parameter.
22      */
23     /**
24     Default configuration used if null is passed to methods that create a
25     transaction.
26     */
27     public static final TransactionConfig DEFAULT = new TransactionConfig();
28 
29     /* package */
checkNull(TransactionConfig config)30     static TransactionConfig checkNull(TransactionConfig config) {
31         return (config == null) ? DEFAULT : config;
32     }
33 
34     private boolean bulk = false;
35     private boolean readUncommitted = false;
36     private boolean readCommitted = false;
37     private boolean noSync = false;
38     private boolean noWait = false;
39     private boolean snapshot = false;
40     private boolean sync = false;
41     private boolean writeNoSync = false;
42     private boolean wait = false;
43 
44     /**
45     An instance created using the default constructor is initialized
46     with the system's default settings.
47     */
TransactionConfig()48     public TransactionConfig() {
49     }
50 
51     /**
52         Configure the transaction for read committed isolation.
53     <p>
54     This ensures the stability of the current data item read by the
55     cursor but permits data read by this transaction to be modified or
56     deleted prior to the commit of the transaction.
57     <p>
58     @param readCommitted
59     If true, configure the transaction for read committed isolation.
60     */
setReadCommitted(final boolean readCommitted)61     public void setReadCommitted(final boolean readCommitted) {
62         this.readCommitted = readCommitted;
63     }
64 
65     /**
66         Return if the transaction is configured for read committed isolation.
67     <p>
68     @return
69     If the transaction is configured for read committed isolation.
70     */
getReadCommitted()71     public boolean getReadCommitted() {
72         return readCommitted;
73     }
74 
75     /**
76         Configure the transaction for read committed isolation.
77     <p>
78     This ensures the stability of the current data item read by the
79     cursor but permits data read by this transaction to be modified or
80     deleted prior to the commit of the transaction.
81     <p>
82     @param degree2
83     If true, configure the transaction for read committed isolation.
84         <p>
85     @deprecated This has been replaced by {@link #setReadCommitted} to conform to ANSI
86     database isolation terminology.
87     */
88 	@Deprecated
setDegree2(final boolean degree2)89     public void setDegree2(final boolean degree2) {
90         setReadCommitted(degree2);
91     }
92 
93     /**
94         Return if the transaction is configured for read committed isolation.
95     <p>
96     @return
97     If the transaction is configured for read committed isolation.
98         <p>
99     @deprecated This has been replaced by {@link #getReadCommitted} to conform to ANSI
100     database isolation terminology.
101     */
102 	@Deprecated
getDegree2()103     public boolean getDegree2() {
104         return getReadCommitted();
105     }
106 
107     /**
108         Configure read operations performed by the transaction to return modified
109     but not yet committed data.
110     <p>
111     @param readUncommitted
112     If true, configure read operations performed by the transaction to return
113     modified but not yet committed data.
114     */
setReadUncommitted(final boolean readUncommitted)115     public void setReadUncommitted(final boolean readUncommitted) {
116         this.readUncommitted = readUncommitted;
117     }
118 
119     /**
120         Return if read operations performed by the transaction are configured to
121     return modified but not yet committed data.
122     <p>
123     @return
124     If read operations performed by the transaction are configured to return
125     modified but not yet committed data.
126     */
getReadUncommitted()127     public boolean getReadUncommitted() {
128         return readUncommitted;
129     }
130 
131     /**
132         Configure read operations performed by the transaction to return modified
133     but not yet committed data.
134     <p>
135     @param dirtyRead
136     If true, configure read operations performed by the transaction to return
137     modified but not yet committed data.
138         <p>
139     @deprecated This has been replaced by {@link #setReadUncommitted} to conform to ANSI
140     database isolation terminology.
141     */
142 	@Deprecated
setDirtyRead(final boolean dirtyRead)143     public void setDirtyRead(final boolean dirtyRead) {
144         setReadUncommitted(dirtyRead);
145     }
146 
147     /**
148         Return if read operations performed by the transaction are configured to
149     return modified but not yet committed data.
150     <p>
151     @return
152     If read operations performed by the transaction are configured to return
153     modified but not yet committed data.
154         <p>
155     @deprecated This has been replaced by {@link #getReadUncommitted} to conform to ANSI
156     database isolation terminology.
157     */
158 	@Deprecated
getDirtyRead()159     public boolean getDirtyRead() {
160         return getReadUncommitted();
161     }
162 
163     /**
164     Configure the transaction to not write or synchronously flush the log
165     it when commits.
166     <p>
167     This behavior may be set for a database environment using the
168     Environment.setMutableConfig method. Any value specified to this method
169     overrides that setting.
170     <p>
171     The default is false for this class and the database environment.
172     <p>
173     @param noSync
174     If true, transactions exhibit the ACI (atomicity, consistency, and
175     isolation) properties, but not D (durability); that is, database
176     integrity will be maintained, but if the application or system
177     fails, it is possible some number of the most recently committed
178     transactions may be undone during recovery. The number of
179     transactions at risk is governed by how many log updates can fit
180     into the log buffer, how often the operating system flushes dirty
181     buffers to disk, and how often the log is checkpointed.
182     */
setNoSync(final boolean noSync)183     public void setNoSync(final boolean noSync) {
184         this.noSync = noSync;
185     }
186 
187     /**
188     Return if the transaction is configured to not write or synchronously
189     flush the log it when commits.
190     <p>
191     @return
192     If the transaction is configured to not write or synchronously flush
193     the log it when commits.
194     */
getNoSync()195     public boolean getNoSync() {
196         return noSync;
197     }
198 
199     /**
200     Configure the transaction to not wait if a lock request cannot be
201     immediately granted.
202     <p>
203     The default is false for this class and the database environment.
204     <p>
205     @param noWait
206     If true, transactions will not wait if a lock request cannot be
207     immediately granted, instead {@link com.sleepycat.db.DeadlockException DeadlockException} will be thrown.
208     */
setNoWait(final boolean noWait)209     public void setNoWait(final boolean noWait) {
210         this.noWait = noWait;
211     }
212 
213     /**
214     Return if the transaction is configured to not wait if a lock
215     request cannot be immediately granted.
216     <p>
217     @return
218     If the transaction is configured to not wait if a lock request
219     cannot be immediately granted.
220     */
getNoWait()221     public boolean getNoWait() {
222         return noWait;
223     }
224 
225     /**
226     This transaction will execute with snapshot isolation.  For databases
227     configured with {@link DatabaseConfig#setMultiversion}, data values
228     will be read as they are when the transaction begins, without taking
229     read locks.
230     <p>
231     Updates operations performed in the transaction will cause a
232     {@link DeadlockException} to be thrown if data is modified
233     between reading and writing it.
234     @param snapshot if this transaction will execute with snapshot isolation
235     */
setSnapshot(final boolean snapshot)236     public void setSnapshot(final boolean snapshot) {
237         this.snapshot = snapshot;
238     }
239 
240     /**
241 Return true if the transaction is configured for Snapshot Isolation.
242 <p>
243 This method may be called at any time during the life of the application.
244 <p>
245 @return
246 True if the transaction is configured for Snapshot Isolation.
247     */
getSnapshot()248     public boolean getSnapshot() {
249         return snapshot;
250     }
251 
252     /**
253     Configure the transaction to write and synchronously flush the log
254     it when commits.
255     <p>
256     This behavior may be set for a database environment using the
257     Environment.setMutableConfig method. Any value specified to this
258     method overrides that setting.
259     <p>
260     The default is false for this class and true for the database
261     environment.
262     <p>
263     If true is passed to both setSync and setNoSync, setSync will take
264     precedence.
265     <p>
266     @param sync
267     If true, transactions exhibit all the ACID (atomicity, consistency,
268     isolation, and durability) properties.
269     */
setSync(final boolean sync)270     public void setSync(final boolean sync) {
271         this.sync = sync;
272     }
273 
274     /**
275     Return if the transaction is configured to write and synchronously
276     flush the log it when commits.
277     <p>
278     @return
279     If the transaction is configured to write and synchronously flush
280     the log it when commits.
281     */
getSync()282     public boolean getSync() {
283         return sync;
284     }
285 
286     /**
287     Configure the transaction to wait if a lock request cannot be
288     immediately granted.
289     <p>
290     The default is true unless {@link EnvironmentConfig#setTxnNoWait} is called.
291     <p>
292     @param wait
293     If true, transactions will wait if a lock request cannot be
294     immediately granted, instead {@link com.sleepycat.db.DeadlockException DeadlockException} will be thrown.
295     */
setWait(final boolean wait)296     public void setWait(final boolean wait) {
297         this.wait = wait;
298     }
299 
300     /**
301     Return if the transaction is configured to wait if a lock
302     request cannot be immediately granted.
303     <p>
304     @return
305     If the transaction is configured to wait if a lock request
306     cannot be immediately granted.
307     */
getWait()308     public boolean getWait() {
309         return wait;
310     }
311 
312     /**
313     Configure the transaction to write but not synchronously flush the log
314     it when commits.
315     <p>
316     This behavior may be set for a database environment using the
317     Environment.setMutableConfig method. Any value specified to this method
318     overrides that setting.
319     <p>
320     The default is false for this class and the database environment.
321     <p>
322     @param writeNoSync
323     If true, transactions exhibit the ACI (atomicity, consistency, and
324     isolation) properties, but not D (durability); that is, database
325     integrity will be maintained, but if the operating system
326     fails, it is possible some number of the most recently committed
327     transactions may be undone during recovery. The number of
328     transactions at risk is governed by how often the operating system
329     flushes dirty buffers to disk, and how often the log is
330     checkpointed.
331     */
setWriteNoSync(final boolean writeNoSync)332     public void setWriteNoSync(final boolean writeNoSync) {
333         this.writeNoSync = writeNoSync;
334     }
335 
336     /**
337     Return if the transaction is configured to write but not synchronously
338     flush the log it when commits.
339     <p>
340     @return
341     If the transaction is configured to not write or synchronously flush
342     the log it when commits.
343     */
getWriteNoSync()344     public boolean getWriteNoSync() {
345         return writeNoSync;
346     }
347 
348     /**
349     Configures the transaction to enable the transactional bulk insert
350     optimization.  When this attribute is set, the transaction will avoid
351     logging the contents of insertions on newly allocated database pages.
352     In a transaction that inserts a large number of new records, the I/O
353     savings of choosing this option can be significant.  Users of this
354     option should be aware of several issues.  When the optimization is in
355     effect, page allocations that extend the database file are logged as
356     usual; this allows transaction aborts to work correctly, both online
357     and during recovery.  At commit time, the database's pages are flushed
358     to disk, eliminating the need to roll-forward the transaction during
359     normal recovery.  However, there are other recovery operations that
360     depend on roll-forward, and care must be taken when Bulk-enabled
361     transactions interact with them.  In particular, Bulk is
362     incompatible with replication, and is simply ignored when replication
363     is enabled.  Also, hot backup procedures must follow a particular
364     protocol, introduced in 11gr2.5.1, to set a flag in the environment
365     before starting to copy files.  It is especially important to note
366     that incremental hot backups can be invalidated by use of the bulk
367     insert optimization.  Please see the hot backup description in the
368     <i>Getting Started with Transactions Guide</i>, and the description of the
369     HotbackupInProgress attribute in
370     {@link com.sleepycat.db.EnvironmentConfig EnvironmentConfig}
371     for further information.
372     <p>
373     The bulk insert optimization is effective only for
374     top-level transactions.
375     <p>
376     @param bulk
377     If true, configure the transaction to enable the bulk optimization.
378     */
setBulk(final boolean bulk)379     public void setBulk(final boolean bulk) {
380 	this.bulk = bulk;
381     }
382 
383     /**
384     Return true if the Bulk attribute is set.
385     <p>
386     @return
387     The current setting of the Bulk attribute.
388     */
getBulk()389     public boolean getBulk() {
390 	return this.bulk;
391     }
392 
beginTransaction(final DbEnv dbenv, final DbTxn parent)393     DbTxn beginTransaction(final DbEnv dbenv, final DbTxn parent)
394         throws DatabaseException {
395 
396         int flags = 0;
397         flags |= readCommitted ? DbConstants.DB_READ_COMMITTED : 0;
398         flags |= readUncommitted ? DbConstants.DB_READ_UNCOMMITTED : 0;
399         flags |= noSync ? DbConstants.DB_TXN_NOSYNC : 0;
400         flags |= noWait ? DbConstants.DB_TXN_NOWAIT : 0;
401         flags |= snapshot ? DbConstants.DB_TXN_SNAPSHOT : 0;
402         flags |= sync ? DbConstants.DB_TXN_SYNC : 0;
403         flags |= wait ? DbConstants.DB_TXN_WAIT : 0;
404         flags |= writeNoSync ? DbConstants.DB_TXN_WRITE_NOSYNC : 0;
405 	flags |= bulk ? DbConstants.DB_TXN_BULK : 0;
406 
407         return dbenv.txn_begin(parent, flags);
408     }
409 }
410