diff options
Diffstat (limited to 'docs/programmer_reference/transapp_put.html')
| -rw-r--r-- | docs/programmer_reference/transapp_put.html | 252 |
1 files changed, 142 insertions, 110 deletions
diff --git a/docs/programmer_reference/transapp_put.html b/docs/programmer_reference/transapp_put.html index 289e1746..9f042e07 100644 --- a/docs/programmer_reference/transapp_put.html +++ b/docs/programmer_reference/transapp_put.html @@ -14,7 +14,7 @@ <body> <div xmlns="" class="navheader"> <div class="libver"> - <p>Library Version 11.2.5.3</p> + <p>Library Version 12.1.6.1</p> </div> <table width="100%" summary="Navigation header"> <tr> @@ -22,9 +22,7 @@ </tr> <tr> <td width="20%" align="left"><a accesskey="p" href="transapp_data_open.html">Prev</a> </td> - <th width="60%" align="center">Chapter 11. - Berkeley DB Transactional Data Store Applications - </th> + <th width="60%" align="center">Chapter 11. Berkeley DB Transactional Data Store Applications </th> <td width="20%" align="right"> <a accesskey="n" href="transapp_atomicity.html">Next</a></td> </tr> </table> @@ -38,32 +36,46 @@ </div> </div> </div> - <p>The first reason listed for using transactions was recoverability. Any -logical change to a database may require multiple changes to underlying -data structures. For example, modifying a record in a Btree may require -leaf and internal pages to split, so a single <a href="../api_reference/C/dbput.html" class="olink">DB->put()</a> method -call can potentially require that multiple physical database pages be -written. If only some of those pages are written and then the system -or application fails, the database is left inconsistent and cannot be -used until it has been recovered; that is, until the partially completed -changes have been undone.</p> - <p><span class="emphasis"><em>Write-ahead-logging</em></span> is the term that describes the underlying -implementation that Berkeley DB uses to ensure recoverability. What it means -is that before any change is made to a database, information about the -change is written to a database log. During recovery, the log is read, -and databases are checked to ensure that changes described in the log -for committed transactions appear in the database. Changes that appear -in the database but are related to aborted or unfinished transactions -in the log are undone from the database.</p> - <p>For recoverability after application or system failure, operations that -modify the database must be protected by transactions. More -specifically, operations are not recoverable unless a transaction is -begun and each operation is associated with the transaction via the -Berkeley DB interfaces, and then the transaction successfully committed. This -is true even if logging is turned on in the database environment.</p> - <p>Here is an example function that updates a record in a database in a -transactionally protected manner. The function takes a key and data -items as arguments and then attempts to store them into the database.</p> + <p> + The first reason listed for using transactions was + recoverability. Any logical change to a database may require + multiple changes to underlying data structures. For example, + modifying a record in a Btree may require leaf and internal + pages to split, so a single <a href="../api_reference/C/dbput.html" class="olink">DB->put()</a> method call can + potentially require that multiple physical database pages be + written. If only some of those pages are written and then the + system or application fails, the database is left inconsistent + and cannot be used until it has been recovered; that is, until + the partially completed changes have been undone. + </p> + <p> + <span class="emphasis"><em>Write-ahead-logging</em></span> is the term that + describes the underlying implementation that Berkeley DB uses + to ensure recoverability. What it means is that before any + change is made to a database, information about the change is + written to a database log. During recovery, the log is read, + and databases are checked to ensure that changes described in + the log for committed transactions appear in the database. + Changes that appear in the database but are related to aborted + or unfinished transactions in the log are undone from the + database. + </p> + <p> + For recoverability after application or system failure, + operations that modify the database must be protected by + transactions. More specifically, operations are not + recoverable unless a transaction is begun and each operation + is associated with the transaction via the Berkeley DB + interfaces, and then the transaction successfully committed. + This is true even if logging is turned on in the database + environment. + </p> + <p> + Here is an example function that updates a record in a + database in a transactionally protected manner. The function + takes a key and data items as arguments and then attempts to + store them into the database. + </p> <pre class="programlisting">int main(int argc, char *argv) { @@ -145,91 +157,111 @@ add_fruit(DB_ENV *dbenv, DB *db, char *fruit, char *name) } } }</strong></span></pre> - <p>Berkeley DB also uses transactions to recover from deadlock. Database -operations (that is, any call to a function underlying the handles -returned by <a href="../api_reference/C/dbopen.html" class="olink">DB->open()</a> and <a href="../api_reference/C/dbcursor.html" class="olink">DB->cursor()</a>) are usually -performed on behalf of a unique locker. Transactions can be used to -perform multiple calls on behalf of the same locker within a single -thread of control. For example, consider the case in which an -application uses a cursor scan to locate a record and then the -application accesses another other item in the database, based on the -key returned by the cursor, without first closing the cursor. If these -operations are done using default locker IDs, they may conflict. If the -locks are obtained on behalf of a transaction, using the transaction's -locker ID instead of the database handle's locker ID, the operations -will not conflict.</p> - <p>There is a new error return in this function that you may not have seen -before. In transactional (not Concurrent Data Store) applications -supporting both readers and writers, or just multiple writers, Berkeley DB -functions have an additional possible error return: -<a class="link" href="program_errorret.html#program_errorret.DB_LOCK_DEADLOCK">DB_LOCK_DEADLOCK</a>. This means two threads of control deadlocked, -and the thread receiving the <code class="literal">DB_LOCK_DEADLOCK</code> error return has -been selected to discard its locks in order to resolve the problem. -When an application receives a <code class="literal">DB_LOCK_DEADLOCK</code> return, the -correct action is to close any cursors involved in the operation and -abort any enclosing transaction. In the sample code, any time the -<a href="../api_reference/C/dbput.html" class="olink">DB->put()</a> method returns <code class="literal">DB_LOCK_DEADLOCK</code>, <a href="../api_reference/C/txnabort.html" class="olink">DB_TXN->abort()</a> is -called (which releases the transaction's Berkeley DB resources and undoes any -partial changes to the databases), and then the transaction is retried -from the beginning.</p> - <p>There is no requirement that the transaction be attempted again, but -that is a common course of action for applications. Applications may -want to set an upper bound on the number of times an operation will be -retried because some operations on some data sets may simply be unable -to succeed. For example, updating all of the pages on a large Web site -during prime business hours may simply be impossible because of the high -access rate to the database.</p> - <p>The <a href="../api_reference/C/txnabort.html" class="olink">DB_TXN->abort()</a> method is called in error cases other than deadlock. -Any time an error occurs, such that a transactionally protected set of -operations cannot complete successfully, the transaction must be -aborted. While deadlock is by far the most common of these errors, -there are other possibilities; for example, running out of disk space -for the filesystem. In Berkeley DB transactional applications, there are -three classes of error returns: "expected" errors, "unexpected but -recoverable" errors, and a single "unrecoverable" error. Expected -errors are errors like -<a class="link" href="program_errorret.html#program_errorret.DB_NOTFOUND">DB_NOTFOUND</a>, -which indicates that a -searched-for key item is not present in the database. Applications may -want to explicitly test for and handle this error, or, in the case where -the absence of a key implies the enclosing transaction should fail, -simply call <a href="../api_reference/C/txnabort.html" class="olink">DB_TXN->abort()</a>. Unexpected but recoverable errors are -errors like -<a class="link" href="program_errorret.html#program_errorret.DB_LOCK_DEADLOCK">DB_LOCK_DEADLOCK</a>, -which indicates that an operation -has been selected to resolve a deadlock, or a system error such as EIO, -which likely indicates that the filesystem has no available disk space. -Applications must immediately call <a href="../api_reference/C/txnabort.html" class="olink">DB_TXN->abort()</a> when these returns -occur, as it is not possible to proceed otherwise. The only -unrecoverable error is -<a class="link" href="program_errorret.html#program_errorret.DB_RUNRECOVERY">DB_RUNRECOVERY</a>, -which indicates that the -system must stop and recovery must be run.</p> - <p>The above code can be simplified in the case of a transaction comprised -entirely of a single database put or delete operation, as operations -occurring in transactional databases are implicitly transaction -protected. For example, in a transactional database, the above code -could be more simply written as:</p> + <p> + Berkeley DB also uses transactions to recover from deadlock. + Database operations (that is, any call to a function + underlying the handles returned by <a href="../api_reference/C/dbopen.html" class="olink">DB->open()</a> and <a href="../api_reference/C/dbcursor.html" class="olink">DB->cursor()</a>) + are usually performed on behalf of a unique locker. + Transactions can be used to perform multiple calls on behalf + of the same locker within a single thread of control. For + example, consider the case in which an application uses a + cursor scan to locate a record and then the application + accesses another other item in the database, based on the key + returned by the cursor, without first closing the cursor. If + these operations are done using default locker IDs, they may + conflict. If the locks are obtained on behalf of a + transaction, using the transaction's locker ID instead of the + database handle's locker ID, the operations will not + conflict. + </p> + <p> + There is a new error return in this function that you may + not have seen before. In transactional (not Concurrent Data + Store) applications supporting both readers and writers, or + just multiple writers, Berkeley DB functions have an + additional possible error return: <a class="link" href="program_errorret.html#program_errorret.DB_LOCK_DEADLOCK"> + DB_LOCK_DEADLOCK</a>. This means two threads of + control deadlocked, and the thread receiving the + <code class="literal">DB_LOCK_DEADLOCK</code> error return has been + selected to discard its locks in order to resolve the problem. + When an application receives a + <code class="literal">DB_LOCK_DEADLOCK</code> return, the correct + action is to close any cursors involved in the operation and + abort any enclosing transaction. In the sample code, any time + the <a href="../api_reference/C/dbput.html" class="olink">DB->put()</a> method returns + <code class="literal">DB_LOCK_DEADLOCK</code>, <a href="../api_reference/C/txnabort.html" class="olink">DB_TXN->abort()</a> is called + (which releases the transaction's Berkeley DB resources and + undoes any partial changes to the databases), and then the + transaction is retried from the beginning. + </p> + <p> + There is no requirement that the transaction be attempted + again, but that is a common course of action for applications. + Applications may want to set an upper bound on the number of + times an operation will be retried because some operations on + some data sets may simply be unable to succeed. For example, + updating all of the pages on a large Web site during prime + business hours may simply be impossible because of the high + access rate to the database. + </p> + <p> + The <a href="../api_reference/C/txnabort.html" class="olink">DB_TXN->abort()</a> method is called in error cases other than + deadlock. Any time an error occurs, such that a + transactionally protected set of operations cannot complete + successfully, the transaction must be aborted. While deadlock + is by far the most common of these errors, there are other + possibilities; for example, running out of disk space for the + filesystem. In Berkeley DB transactional applications, there + are three classes of error returns: "expected" errors, + "unexpected but recoverable" errors, and a single + "unrecoverable" error. Expected errors are errors like <a class="link" href="program_errorret.html#program_errorret.DB_NOTFOUND">DB_NOTFOUND</a>, + which indicates that a searched-for key item is not present in + the database. Applications may want to explicitly test for and + handle this error, or, in the case where the absence of a key + implies the enclosing transaction should fail, simply call + <a href="../api_reference/C/txnabort.html" class="olink">DB_TXN->abort()</a>. Unexpected but recoverable errors are errors like + <a class="link" href="program_errorret.html#program_errorret.DB_LOCK_DEADLOCK">DB_LOCK_DEADLOCK</a>, + which indicates that an operation has been selected to resolve a + deadlock, or a system error such as EIO, which likely indicates + that the filesystem has no available disk space. Applications must + immediately call <a href="../api_reference/C/txnabort.html" class="olink">DB_TXN->abort()</a> when these returns occur, as it is not + possible to proceed otherwise. The only unrecoverable error is + <a class="link" href="program_errorret.html#program_errorret.DB_RUNRECOVERY">DB_RUNRECOVERY</a>, + which indicates that the system + must stop and recovery must be run. + </p> + <p> + The above code can be simplified in the case of a + transaction comprised entirely of a single database put or + delete operation, as operations occurring in transactional + databases are implicitly transaction protected. For example, + in a transactional database, the above code could be more + simply written as: + </p> <pre class="programlisting"> <strong class="userinput"><code>for (fail = 0; fail++ <= MAXIMUM_RETRY && (ret = db->put(db, NULL, &key, &data, 0)) == DB_LOCK_DEADLOCK;) continue; return (ret == 0 ? 0 : 1);</code></strong></pre> - <p>and the underlying transaction would be automatically handled by Berkeley DB.</p> - <p>Programmers should not attempt to enumerate all possible error returns -in their software. Instead, they should explicitly handle expected -returns and default to aborting the transaction for the rest. It is -entirely the choice of the programmer whether to check for -<a class="link" href="program_errorret.html#program_errorret.DB_RUNRECOVERY">DB_RUNRECOVERY</a> -explicitly or not — attempting new Berkeley DB -operations after -<a class="link" href="program_errorret.html#program_errorret.DB_RUNRECOVERY">DB_RUNRECOVERY</a> -is returned does not worsen the -situation. Alternatively, using the <a href="../api_reference/C/envevent_notify.html" class="olink">DB_ENV->set_event_notify()</a> method to -handle an unrecoverable error and simply doing some number of -abort-and-retry cycles for any unexpected Berkeley DB or system error in the -mainline code often results in the simplest and cleanest application -code.</p> + <p> + and the underlying transaction would be automatically + handled by Berkeley DB. + </p> + <p> + Programmers should not attempt to enumerate all possible + error returns in their software. Instead, they should + explicitly handle expected returns and default to aborting the + transaction for the rest. It is entirely the choice of the + programmer whether to check for <a class="link" href="program_errorret.html#program_errorret.DB_RUNRECOVERY"> + DB_RUNRECOVERY</a> explicitly or not — + attempting new Berkeley DB operations after <a class="link" href="program_errorret.html#program_errorret.DB_RUNRECOVERY">DB_RUNRECOVERY</a> + is returned does not worsen the + situation. Alternatively, using the <a href="../api_reference/C/envevent_notify.html" class="olink">DB_ENV->set_event_notify()</a> method + to handle an unrecoverable error and simply doing some number + of abort-and-retry cycles for any unexpected Berkeley DB or + system error in the mainline code often results in the + simplest and cleanest application code. + </p> </div> <div class="navfooter"> <hr /> |
