summaryrefslogtreecommitdiff
path: root/bdb/docs/ref/transapp/inc.html
diff options
context:
space:
mode:
Diffstat (limited to 'bdb/docs/ref/transapp/inc.html')
-rw-r--r--bdb/docs/ref/transapp/inc.html201
1 files changed, 0 insertions, 201 deletions
diff --git a/bdb/docs/ref/transapp/inc.html b/bdb/docs/ref/transapp/inc.html
deleted file mode 100644
index 35cf67d7efa..00000000000
--- a/bdb/docs/ref/transapp/inc.html
+++ /dev/null
@@ -1,201 +0,0 @@
-<!--$Id: inc.so,v 1.6 2000/08/08 19:58:20 bostic Exp $-->
-<!--Copyright 1997, 1998, 1999, 2000 by Sleepycat Software, Inc.-->
-<!--All rights reserved.-->
-<html>
-<head>
-<title>Berkeley DB Reference Guide: Atomicity</title>
-<meta name="description" content="Berkeley DB: An embedded database programmatic toolkit.">
-<meta name="keywords" content="embedded,database,programmatic,toolkit,b+tree,btree,hash,hashing,transaction,transactions,locking,logging,access method,access methods,java,C,C++">
-</head>
-<body bgcolor=white>
-<table><tr valign=top>
-<td><h3><dl><dt>Berkeley DB Reference Guide:<dd>Transaction Protected Applications</dl></h3></td>
-<td width="1%"><a href="../../ref/transapp/put.html"><img src="../../images/prev.gif" alt="Prev"></a><a href="../../ref/toc.html"><img src="../../images/ref.gif" alt="Ref"></a><a href="../../ref/transapp/read.html"><img src="../../images/next.gif" alt="Next"></a>
-</td></tr></table>
-<p>
-<h1 align=center>Atomicity</h1>
-<p>The third reason listed for using transactions was atomicity. Consider
-an application suite where multiple threads of control (multiple
-processes or threads in one or more processes) are changing the values
-associated with a key in one or more databases. Specifically, they are
-taking the current value, incrementing it, and then storing it back into
-the database.
-<p>Such an application requires atomicity. Since we want to change a value
-in the database, we must make sure that once we read it, no other thread
-of control modifies it. For example, assume that both thread #1 and
-thread #2 are doing similar operations in the database, where thread #1
-is incrementing records by 3, and thread #2 is incrementing records by
-5. We want to increment the record by a total of 8. If the operations
-interleave in the right (well, wrong) order, that is not what will
-happen:
-<p><blockquote><pre>thread #1 <b>read</b> record: the value is 2
-thread #2 <b>read</b> record: the value is 2
-thread #2 <b>write</b> record + 5 back into the database (new value 7)
-thread #1 <b>write</b> record + 3 back into the database (new value 5)</pre></blockquote>
-<p>As you can see, instead of incrementing the record by a total of 8,
-we've only incremented it by 3, because thread #1 overwrote thread #2's
-change. By wrapping the operations in transactions, we ensure that this
-cannot happen. In a transaction, when the first thread reads the
-record, locks are acquired that will not be released until the
-transaction finishes, guaranteeing that all other readers and writers
-will block, waiting for the first thread's transaction to complete (or
-to be aborted).
-<p>Here is an example function that does transaction-protected increments
-on database records to ensure atomicity.
-<p><blockquote><pre>int
-main(int argc, char *argv)
-{
- extern char *optarg;
- extern int optind;
- DB *db_cats, *db_color, *db_fruit;
- DB_ENV *dbenv;
- pthread_t ptid;
- int ch;
-<p>
- while ((ch = getopt(argc, argv, "")) != EOF)
- switch (ch) {
- case '?':
- default:
- usage();
- }
- argc -= optind;
- argv += optind;
-<p>
- env_dir_create();
- env_open(&dbenv);
-<p>
- /* Open database: Key is fruit class; Data is specific type. */
- db_open(dbenv, &db_fruit, "fruit", 0);
-<p>
- /* Open database: Key is a color; Data is an integer. */
- db_open(dbenv, &db_color, "color", 0);
-<p>
- /*
- * Open database:
- * Key is a name; Data is: company name, address, cat breeds.
- */
- db_open(dbenv, &db_cats, "cats", 1);
-<p>
- add_fruit(dbenv, db_fruit, "apple", "yellow delicious");
-<p>
-<b> add_color(dbenv, db_color, "blue", 0);
- add_color(dbenv, db_color, "blue", 3);</b>
-<p>
- return (0);
-}
-<p>
-<b>void
-add_color(DB_ENV *dbenv, DB *dbp, char *color, int increment)
-{
- DBT key, data;
- DB_TXN *tid;
- int original, ret;
- char buf64;
-<p>
- /* Initialization. */
- memset(&key, 0, sizeof(key));
- key.data = color;
- key.size = strlen(color);
- memset(&data, 0, sizeof(data));
- data.flags = DB_DBT_MALLOC;
-<p>
- for (;;) {
- /* Begin the transaction. */
- if ((ret = txn_begin(dbenv, NULL, &tid, 0)) != 0) {
- dbenv-&gt;err(dbenv, ret, "txn_begin");
- exit (1);
- }
-<p>
- /*
- * Get the key. If it exists, we increment the value. If it
- * doesn't exist, we create it.
- */
- switch (ret = dbp-&gt;get(dbp, tid, &key, &data, 0)) {
- case 0:
- original = atoi(data.data);
- break;
- case DB_LOCK_DEADLOCK:
- /* Deadlock: retry the operation. */
- if ((ret = txn_abort(tid)) != 0) {
- dbenv-&gt;err(dbenv, ret, "txn_abort");
- exit (1);
- }
- continue;
- case DB_NOTFOUND:
- original = 0;
- break;
- default:
- /* Error: run recovery. */
- dbenv-&gt;err(
- dbenv, ret, "dbc-&gt;get: %s/%d", color, increment);
- exit (1);
- }
- if (data.data != NULL)
- free(data.data);
-<p>
- /* Create the new data item. */
- (void)snprintf(buf, sizeof(buf), "%d", original + increment);
- data.data = buf;
- data.size = strlen(buf) + 1;
-<p>
- /* Store the new value. */
- switch (ret = dbp-&gt;put(dbp, tid, &key, &data, 0)) {
- case 0:
- /* Success: commit the change. */
- if ((ret = txn_commit(tid, 0)) != 0) {
- dbenv-&gt;err(dbenv, ret, "txn_commit");
- exit (1);
- }
- return;
- case DB_LOCK_DEADLOCK:
- /* Deadlock: retry the operation. */
- if ((ret = txn_abort(tid)) != 0) {
- dbenv-&gt;err(dbenv, ret, "txn_abort");
- exit (1);
- }
- break;
- default:
- /* Error: run recovery. */
- dbenv-&gt;err(
- dbenv, ret, "dbc-&gt;put: %s/%d", color, increment);
- exit (1);
- }
- }
-}</b></pre></blockquote>
-<p>Any number of operations, on any number of databases, can be included
-in a single transaction to ensure atomicity of the operations. There
-is, however, a trade-off between the number of operations included in
-a single transaction and both throughput and the possibility of
-deadlock. The reason for this is because transactions acquire locks
-throughout their lifetime, and do not release them until transaction
-commit or abort. So, the more operations included in a transaction,
-the more likely that a transaction will block other operations and that
-deadlock will occur. However, each transaction commit requires a
-synchronous disk I/O, so grouping multiple operations into a transaction
-can increase overall throughput. (There is one exception to this. The
-<a href="../../api_c/env_open.html#DB_TXN_NOSYNC">DB_TXN_NOSYNC</a> option causes transactions to exhibit the ACI
-(atomicity, consistency and isolation) properties, but not D
-(durability), avoiding the synchronous disk I/O on transaction commit
-and greatly increasing transaction throughput for some applications.
-<p>When applications do create complex transactions, they often avoid
-having more than one complex transaction at a time, as simple operations
-like a single <a href="../../api_c/db_put.html">DB-&gt;put</a> are unlikely to deadlock with each other
-or the complex transaction, while multiple complex transactions are
-likely to deadlock with each other as they will both acquire many locks
-over their lifetime. Alternatively, complex transactions can be broken
-up into smaller sets of operations, and each of those sets may be
-encapsulated in a nested transaction. Because nested transactions may
-be individually aborted and retried without causing the entire
-transaction to be aborted, this allows complex transactions to proceed
-even in the face of heavy contention, repeatedly trying the
-sub-operations until they succeed.
-<p>It is also helpful to order operations within a transaction, that is,
-access the databases and items within the databases in the same order,
-to the extent possible, in all transactions. Accessing databases and
-items in different orders greatly increases the likelihood of operations
-being blocked and failing due to deadlocks.
-<table><tr><td><br></td><td width="1%"><a href="../../ref/transapp/put.html"><img src="../../images/prev.gif" alt="Prev"></a><a href="../../ref/toc.html"><img src="../../images/ref.gif" alt="Ref"></a><a href="../../ref/transapp/read.html"><img src="../../images/next.gif" alt="Next"></a>
-</td></tr></table>
-<p><font size=1><a href="http://www.sleepycat.com">Copyright Sleepycat Software</a></font>
-</body>
-</html>