File: usingtxns.html

package info (click to toggle)
db5.3 5.3.28%2Bdfsg1-0.5
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 158,360 kB
  • sloc: ansic: 448,411; java: 111,824; tcl: 80,544; sh: 44,326; cs: 33,697; cpp: 21,604; perl: 14,557; xml: 10,799; makefile: 4,077; yacc: 1,003; awk: 965; sql: 801; erlang: 342; python: 216; php: 24; asm: 14
file content (459 lines) | stat: -rw-r--r-- 17,190 bytes parent folder | download | duplicates (8)
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
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <title>Chapter 3. Transaction Basics</title>
    <link rel="stylesheet" href="gettingStarted.css" type="text/css" />
    <meta name="generator" content="DocBook XSL Stylesheets V1.73.2" />
    <link rel="start" href="index.html" title="Getting Started with Berkeley DB Transaction Processing" />
    <link rel="up" href="index.html" title="Getting Started with Berkeley DB Transaction Processing" />
    <link rel="prev" href="envopen.html" title="Opening a Transactional Environment and Store or Database" />
    <link rel="next" href="nodurabletxn.html" title="Non-Durable Transactions" />
  </head>
  <body>
    <div xmlns="" class="navheader">
      <div class="libver">
        <p>Library Version 11.2.5.3</p>
      </div>
      <table width="100%" summary="Navigation header">
        <tr>
          <th colspan="3" align="center">Chapter 3. Transaction Basics</th>
        </tr>
        <tr>
          <td width="20%" align="left"><a accesskey="p" href="envopen.html">Prev</a> </td>
          <th width="60%" align="center"> </th>
          <td width="20%" align="right"> <a accesskey="n" href="nodurabletxn.html">Next</a></td>
        </tr>
      </table>
      <hr />
    </div>
    <div class="chapter" lang="en" xml:lang="en">
      <div class="titlepage">
        <div>
          <div>
            <h2 class="title"><a id="usingtxns"></a>Chapter 3. Transaction Basics</h2>
          </div>
        </div>
      </div>
      <div class="toc">
        <p>
          <b>Table of Contents</b>
        </p>
        <dl>
          <dt>
            <span class="sect1">
              <a href="usingtxns.html#commitresults">Committing a Transaction</a>
            </span>
          </dt>
          <dt>
            <span class="sect1">
              <a href="nodurabletxn.html">Non-Durable Transactions</a>
            </span>
          </dt>
          <dt>
            <span class="sect1">
              <a href="abortresults.html">Aborting a Transaction</a>
            </span>
          </dt>
          <dt>
            <span class="sect1">
              <a href="autocommit.html">Auto Commit</a>
            </span>
          </dt>
          <dt>
            <span class="sect1">
              <a href="nestedtxn.html">Nested Transactions</a>
            </span>
          </dt>
          <dt>
            <span class="sect1">
              <a href="txncursor.html">Transactional Cursors</a>
            </span>
          </dt>
          <dd>
            <dl>
              <dt>
                <span class="sect2">
                  <a href="txncursor.html#dplcursors">Using Transactional DPL Cursors</a>
                </span>
              </dt>
            </dl>
          </dd>
          <dt>
            <span class="sect1">
              <a href="txnindices.html">Secondary Indices with Transaction Applications</a>
            </span>
          </dt>
          <dt>
            <span class="sect1">
              <a href="maxtxns.html">Configuring the Transaction Subsystem</a>
            </span>
          </dt>
        </dl>
      </div>
      <p>
        Once you have enabled transactions for your environment and your databases,
        you can use them to protect your database operations. You do this by
        acquiring a transaction handle and then using that handle for any
        database operation that you want to participate in that transaction.
     </p>
      <p>
        You obtain a transaction handle using the
        
        
        <span><code class="methodname">Environment.beginTransaction()</code> method.</span>
        
        
     </p>
      <p>
        Once you have completed all of the operations that you want to include
        in the transaction, you must commit the transaction using the 
        
        
        <span><code class="methodname">Transaction.commit()</code> method.</span>
        
        
        
    </p>
      <p>
        If, for any reason, you want to abandon the transaction, you abort
        it using 
        
        
        <span><code class="methodname">Transaction.abort()</code>.</span>
        
        

        
    </p>
      <p>
        Any transaction handle that has been committed or aborted can no longer
        be used by your application.
    </p>
      <p>
        Finally, you must make sure that all transaction handles are either
        committed or aborted before closing your databases and environment.
    </p>
      <div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">
        <h3 class="title">Note</h3>
        <p>
            If you only want to transaction protect a single database write operation, you can use auto commit to 
            perform the transaction administration. When you use auto commit, you do not need an explicit transaction
            handle. See <a class="xref" href="autocommit.html" title="Auto Commit">Auto Commit</a> for more information.
        </p>
      </div>
      <p>
        For example, the following example opens a transactional-enabled environment and
        store, obtains a transaction handle, and then performs a write
        operation under its protection. In the event of any failure in the
        write operation, the transaction is aborted and the store is left in a
        state as if no operations had ever been attempted in the first place.

    </p>
      <pre class="programlisting">package persist.txn;

import com.sleepycat.db.DatabaseException;
import com.sleepycat.db.Environment;
import com.sleepycat.db.EnvironmentConfig;
import com.sleepycat.db.Transaction;

import com.sleepycat.persist.EntityStore;
import com.sleepycat.persist.StoreConfig;

import java.io.File;
import java.io.FileNotFoundException;

...

Environment myEnv = null;
EntityStore store = null;

// Our convenience data accessor class, used for easy access to 
// EntityClass indexes.
DataAccessor da;

try {
    EnvironmentConfig myEnvConfig = new EnvironmentConfig();
    myEnvConfig.setInitializeCache(true);
    myEnvConfig.setInitializeLocking(true);
    myEnvConfig.setInitializeLogging(true);
    myEnvConfig.setTransactional(true);

    StoreConfig storeConfig = new StoreConfig();
    storeConfig.setTransactional(true);

    myEnv = new Environment(new File("/my/env/home"),
                              myEnvConfig);

    EntityStore store = new EntityStore(myEnv, 
                             "EntityStore", storeConfig);

    da = new DataAccessor(store);

    // Assume that Inventory is an entity class.
    Inventory theInventory = new Inventory();
    theInventory.setItemName("Waffles");
    theInventory.setItemSku("waf23rbni");

    Transaction txn = myEnv.beginTransaction(null, null);
        
    try {
        // Put the object to the store using the transaction handle.
        da.inventoryBySku.put(txn, theInventory);

        // Commit the transaction. The data is now safely written to the
        // store.
        txn.commit();
    // If there is a problem, abort the transaction
    } catch (Exception e) {
        if (txn != null) {
            txn.abort();
            txn = null;
        }
    }


} catch (DatabaseException de) {
    // Exception handling goes here
    } catch (FileNotFoundException fnfe) {
    // Exception handling goes here
}</pre>
      <p>
        The same thing can be done with the base API; the
        database in use is left unchanged if the write operation fails:
    </p>
      <pre class="programlisting">package db.txn;

import com.sleepycat.db.Database;
import com.sleepycat.db.DatabaseConfig;
import com.sleepycat.db.DatabaseEntry;
import com.sleepycat.db.DatabaseException;
import com.sleepycat.db.Environment;
import com.sleepycat.db.EnvironmentConfig;
import com.sleepycat.db.Transaction;

import java.io.File;
import java.io.FileNotFoundException;

...

Database myDatabase = null;
Environment myEnv = null;
try {
    EnvironmentConfig myEnvConfig = new EnvironmentConfig();
    myEnvConfig.setInitializeCache(true);
    myEnvConfig.setInitializeLocking(true);
    myEnvConfig.setInitializeLogging(true);
    myEnvConfig.setTransactional(true);

    myEnv = new Environment(new File("/my/env/home"),
                              myEnvConfig);

    // Open the database.
    DatabaseConfig dbConfig = new DatabaseConfig();
    dbConfig.setTransactional(true);
    dbConfig.setType(DatabaseType.BTREE);
    myDatabase = myEnv.openDatabase(null,              // txn handle
                                    "sampleDatabase",  // db file name
                                    null,              // db name
                                    dbConfig);
    String keyString = "thekey";
    String dataString = "thedata";
    DatabaseEntry key = 
        new DatabaseEntry(keyString.getBytes("UTF-8"));
    DatabaseEntry data = 
        new DatabaseEntry(dataString.getBytes("UTF-8"));

    Transaction txn = myEnv.beginTransaction(null, null);
        
    try {
        myDatabase.put(txn, key, data);
        txn.commit();
    } catch (Exception e) {
        if (txn != null) {
            txn.abort();
            txn = null;
        }
    }

} catch (DatabaseException de) {
    // Exception handling goes here
} catch (FileNotFoundException fnfe) {
    // Exception handling goes here
} </pre>
      <div class="sect1" lang="en" xml:lang="en">
        <div class="titlepage">
          <div>
            <div>
              <h2 class="title" style="clear: both"><a id="commitresults"></a>Committing a Transaction</h2>
            </div>
          </div>
        </div>
        <p>
            In order to fully understand what is happening when you commit
            a transaction, you must first understand a little about what
            DB is doing with 
            
            <span>
            the logging subsystem. 
            </span>

            

            Logging causes all database <span>or
                    store</span> write operations to be identified in

            <span>logs, and by default these
            logs are backed by files on disk.  These logs are used to restore your databases 
            <span>or store</span>
            </span>

            
                    
            in the event of a system or application failure, so by performing
            logging, DB ensures the integrity of your data. 
        </p>
        <p>
            Moreover, DB performs <span class="emphasis"><em>write-ahead</em></span>
            logging. This means that information is written to the logs
            <span class="emphasis"><em>before</em></span> the actual database 
            <span>
                    or store
            </span>
            is changed.
            This means that all write activity performed under the
            protection of the transaction is noted in the log before
            the transaction is committed. Be aware, however, that database
            maintains logs in-memory. If you are backing your logs on
            disk, the log information will eventually be written to the log
            files, but while the transaction is on-going the log data may be
            held only in memory.
        </p>
        <p>
            When you commit a transaction, the following occurs:
        </p>
        <div class="itemizedlist">
          <ul type="disc">
            <li>
              <p>
                    A commit record is written to the log. This
                    indicates that the modifications made by the
                    transaction are now permanent. By default, this write is performed synchronously to disk so the
                    commit record arrives in the log files before any other actions are taken.
                </p>
            </li>
            <li>
              <p>
                    Any log information held in memory is (by default)
                    synchronously written to disk. Note that this requirement can be
                    relaxed, depending on the type of commit you perform.
                    See <a class="xref" href="nodurabletxn.html" title="Non-Durable Transactions">Non-Durable Transactions</a> for
                    more information. 
                    <span>Also, if you are
                    maintaining your logs entirely in-memory, then this
                    step will of course not be taken. To configure your
                    logging system for in-memory usage, see
                    <a class="xref" href="logconfig.html#inmemorylogging" title="Configuring In-Memory Logging">Configuring In-Memory Logging</a>.
                    </span>
                </p>
            </li>
            <li>
              <p>
                    All locks held by the transaction are released. This means
                    that read operations performed by other transactions or
                    threads of control can now see the modifications without
                    resorting to uncommitted reads (see <a class="xref" href="isolation.html#dirtyreads" title="Reading Uncommitted Data">Reading Uncommitted Data</a> for more information).
                </p>
            </li>
          </ul>
        </div>
        <p>
            To commit a transaction, you simply call
            
            
            <span><code class="methodname">Transaction.commit()</code>.</span>
            
            
        </p>
        <p>
            Notice that committing a transaction does not necessarily cause data
            modified in your memory cache to be written to the files
            backing your databases on disk. Dirtied database pages are written
            for a number of reasons, but a transactional
            commit is not one of them. The following are the things that can cause a dirtied
            database page to be written to the backing database file:
        </p>
        <div class="itemizedlist">
          <ul type="disc">
            <li>
              <p>
                    Checkpoints.
                </p>
              <p>
                    Checkpoints cause all dirtied pages currently existing
                    in the cache to be written to disk, and a checkpoint
                    record is then written to the logs.  You can run checkpoints
                    explicitly. For more information on checkpoints,
                    see <a class="xref" href="filemanagement.html#checkpoints" title="Checkpoints">Checkpoints</a>.
                </p>
            </li>
            <li>
              <p>
                    Cache is full.
                </p>
              <p>
                    If the in-memory cache fills up, then dirtied pages
                    might be written to disk in order to free up space for other
                    pages that your application needs to use. Note that if
                    dirtied pages are written to the database files, then
                    any log records that describe how those pages were 
                    dirtied are written to disk before the database 
                    pages are written.
                </p>
            </li>
          </ul>
        </div>
        <p>
            Be aware that because your transaction commit caused database
            <span>
                    or store
            </span>
            modifications recorded in your logs to be forced to disk, your modifications
            are by default "persistent" in that they can be recovered in the event of
            an application or system failure. However, recovery time is
            gated by how much data has been modified since the last
            checkpoint, so for applications that perform a lot of writes,
            you may want to run a checkpoint with some frequency.
        </p>
        <p>
                Note that once you have committed a transaction, the transaction
                handle that you used for the transaction is no longer valid. To
                perform database activities under the control of a new
                transaction, you must obtain a fresh transaction handle.
              </p>
      </div>
    </div>
    <div class="navfooter">
      <hr />
      <table width="100%" summary="Navigation footer">
        <tr>
          <td width="40%" align="left"><a accesskey="p" href="envopen.html">Prev</a> </td>
          <td width="20%" align="center"> </td>
          <td width="40%" align="right"> <a accesskey="n" href="nodurabletxn.html">Next</a></td>
        </tr>
        <tr>
          <td width="40%" align="left" valign="top">Opening a Transactional Environment and
            
            <span>Store or Database</span>
            
         </td>
          <td width="20%" align="center">
            <a accesskey="h" href="index.html">Home</a>
          </td>
          <td width="40%" align="right" valign="top"> Non-Durable Transactions</td>
        </tr>
      </table>
    </div>
  </body>
</html>