1<!--$Id: intro.so,v 10.33 2006/11/13 18:05:00 bostic Exp $--> 2<!--Copyright (c) 1997,2008 Oracle. All rights reserved.--> 3<!--See the file LICENSE for redistribution information.--> 4<html> 5<head> 6<title>Berkeley DB Reference Guide: Concurrent Data Store introduction</title> 7<meta name="description" content="Berkeley DB: An embedded database programmatic toolkit."> 8<meta name="keywords" content="embedded,database,programmatic,toolkit,btree,hash,hashing,transaction,transactions,locking,logging,access method,access methods,Java,C,C++"> 9</head> 10<body bgcolor=white> 11<a name="2"><!--meow--></a> 12<table width="100%"><tr valign=top> 13<td><b><dl><dt>Berkeley DB Reference Guide:<dd>Berkeley DB Concurrent Data Store Applications</dl></b></td> 14<td align=right><a href="../env/faq.html"><img src="../../images/prev.gif" alt="Prev"></a><a href="../toc.html"><img src="../../images/ref.gif" alt="Ref"></a><a href="../cam/fail.html"><img src="../../images/next.gif" alt="Next"></a> 15</td></tr></table> 16<p align=center><b>Concurrent Data Store introduction</b></p> 17<p>It is often desirable to have concurrent read-write access to a database 18when there is no need for full recoverability or transaction semantics. 19For this class of applications, Berkeley DB provides interfaces supporting 20deadlock-free, multiple-reader/single writer access to the database. 21This means that at any instant in time, there may be either multiple 22readers accessing data or a single writer modifying data. The 23application is entirely unaware of which is happening, and Berkeley DB 24implements the necessary locking and blocking to ensure this behavior.</p> 25<p>To create Berkeley DB Concurrent Data Store applications, you must first initialize an environment 26by calling <a href="../../api_c/env_open.html">DB_ENV->open</a>. You must specify the <a href="../../api_c/env_open.html#DB_INIT_CDB">DB_INIT_CDB</a> 27and <a href="../../api_c/env_open.html#DB_INIT_MPOOL">DB_INIT_MPOOL</a> flags to that method. It is an error to 28specify any of the other <a href="../../api_c/env_open.html">DB_ENV->open</a> subsystem or recovery 29configuration flags, for example, <a href="../../api_c/env_open.html#DB_INIT_LOCK">DB_INIT_LOCK</a>, 30<a href="../../api_c/env_open.html#DB_INIT_TXN">DB_INIT_TXN</a>, or <a href="../../api_c/env_open.html#DB_RECOVER">DB_RECOVER</a>. All databases must, of 31course, be created in this environment by using the <a href="../../api_c/db_class.html">db_create</a> 32function or <a href="../../api_cxx/db_class.html">Db</a> constructor, and specifying the environment 33as an argument.</p> 34<p>Berkeley DB performs appropriate locking so that safe enforcement of the 35deadlock-free, multiple-reader/single-writer semantic is transparent to 36the application. However, a basic understanding of Berkeley DB Concurrent Data Store locking 37behavior is helpful when writing Berkeley DB Concurrent Data Store applications.</p> 38<p>Berkeley DB Concurrent Data Store 39avoids deadlocks without the need for a deadlock detector by performing 40all locking on an entire database at once (or on an entire environment 41in the case of the <a href="../../api_c/env_set_flags.html#DB_CDB_ALLDB">DB_CDB_ALLDB</a> flag), and by ensuring that at 42any given time only one thread of control is allowed to simultaneously 43hold a read (shared) lock and attempt to acquire a write (exclusive) 44lock.</p> 45<p>All open Berkeley DB cursors hold a read lock, which serves as a guarantee 46that the database will not change beneath them; likewise, all 47non-cursor <a href="../../api_c/db_get.html">DB->get</a> operations temporarily acquire and release 48a read lock that is held during the actual traversal of the database. 49Because read locks will not conflict with each other, any number of 50cursors in any number of threads of control may be open simultaneously, 51and any number of <a href="../../api_c/db_get.html">DB->get</a> operations may be concurrently in 52progress.</p> 53<p>To enforce the rule that only one thread of control at a time can 54attempt to upgrade a read lock to a write lock, however, Berkeley DB must 55forbid multiple cursors from attempting to write concurrently. This is 56done using the <a href="../../api_c/db_cursor.html#DB_WRITECURSOR">DB_WRITECURSOR</a> flag to the <a href="../../api_c/db_cursor.html">DB->cursor</a> method. 57This is the only difference between access method calls in Berkeley DB Concurrent Data Store and 58in the other Berkeley DB products. The <a href="../../api_c/db_cursor.html#DB_WRITECURSOR">DB_WRITECURSOR</a> flag causes the 59newly created cursor to be a "write" cursor; that is, a cursor capable 60of performing writes as well as reads. Only cursors thus created are 61permitted to perform write operations (either deletes or puts), and only 62one such cursor can exist at any given time.</p> 63<p>Any attempt to create a second write cursor or to perform a non-cursor 64write operation while a write cursor is open will block until that write 65cursor is closed. Read cursors may open and perform reads without blocking 66while a write cursor is extant. However, any attempts to actually perform 67a write, either using the write cursor or directly using the 68<a href="../../api_c/db_put.html">DB->put</a> or <a href="../../api_c/db_del.html">DB->del</a> methods, will block until all read cursors 69are closed. This is how the multiple-reader/single-writer semantic is 70enforced, and prevents reads from seeing an inconsistent database state 71that may be an intermediate stage of a write operation.</p> 72<p>By default, Berkeley DB Concurrent Data Store does locking on a per-database basis. For this 73reason, using cursors to access multiple databases in different orders 74in different threads or processes, or leaving cursors open on one 75database while accessing another database, can cause an application to 76hang. If this behavior is a requirement for the application, Berkeley DB 77should be configured to do locking on an environment-wide basis. See 78the <a href="../../api_c/env_set_flags.html#DB_CDB_ALLDB">DB_CDB_ALLDB</a> flag of the <a href="../../api_c/env_set_flags.html">DB_ENV->set_flags</a> function 79for more information.</p> 80<p>With these behaviors, Berkeley DB can guarantee deadlock-free concurrent 81database access, so that multiple threads of control are free to perform 82reads and writes without needing to handle synchronization themselves 83or having to run a deadlock detector. Berkeley DB has no direct knowledge of 84which cursors belong to which threads, so some care must be taken to 85ensure that applications do not inadvertently block themselves, causing 86the application to hang and be unable to proceed.</p> 87<p>As a consequence of the Berkeley DB Concurrent Data Store locking model, the following sequences 88of operations will cause a thread to block itself indefinitely:</p> 89<ol> 90<p><li>Keeping a cursor open while issuing a <a href="../../api_c/db_put.html">DB->put</a> or <a href="../../api_c/db_del.html">DB->del</a> 91access method call. 92<p><li>Attempting to open a write cursor while another cursor is already being 93held open by the same thread of control. Note that it is correct 94operation for one thread of control to attempt to open a write cursor 95or to perform a non-cursor write (<a href="../../api_c/db_put.html">DB->put</a> or <a href="../../api_c/db_del.html">DB->del</a>) 96while a write cursor is already active in another thread. It is only a 97problem if these things are done within a single thread of control -- 98in which case that thread will block and never be able to release the 99lock that is blocking it. 100<p><li>Not testing Berkeley DB error return codes (if any cursor operation returns 101an unexpected error, that cursor must still be closed). 102</ol> 103<p>If the application needs to open multiple cursors in a single thread to 104perform an operation, it can indicate to Berkeley DB that the cursor locks 105should not block each other by creating a Berkeley DB Concurrent Data Store <b>group</b>, using 106<a href="../../api_c/env_cdsgroup_begin.html">DB_ENV->cdsgroup_begin</a>. This creates a locker ID that is shared by all 107cursors opened in the group.</p> 108<p>Berkeley DB Concurrent Data Store groups use a <a href="../../api_c/txn_class.html">DB_TXN</a> handle to indicate the shared locker 109ID to Berkeley DB calls, and call <a href="../../api_c/txn_commit.html">DB_TXN->commit</a> to end the group. This 110is a convenient way to pass the locked ID to the calls where it is 111needed, but should not be confused with the real transactional semantics 112provided by Berkeley DB Transactional Data Store. In particular, Berkeley DB Concurrent Data Store groups do not provide any 113abort or recovery facilities, and have no impact on durability of 114operations.</p> 115<table width="100%"><tr><td><br></td><td align=right><a href="../env/faq.html"><img src="../../images/prev.gif" alt="Prev"></a><a href="../toc.html"><img src="../../images/ref.gif" alt="Ref"></a><a href="../cam/fail.html"><img src="../../images/next.gif" alt="Next"></a> 116</td></tr></table> 117<p><font size=1>Copyright (c) 1996,2008 Oracle. All rights reserved.</font> 118</body> 119</html> 120