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
|
<?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>Read/Modify/Write</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="txnconcurrency.html" title="Chapter 4. Concurrency" />
<link rel="prev" href="exclusivelock.html" title="Exclusive Database Handles" />
<link rel="next" href="txnnowait.html" title="No Wait on Blocks" />
</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">Read/Modify/Write</th>
</tr>
<tr>
<td width="20%" align="left"><a accesskey="p" href="exclusivelock.html">Prev</a> </td>
<th width="60%" align="center">Chapter 4. Concurrency</th>
<td width="20%" align="right"> <a accesskey="n" href="txnnowait.html">Next</a></td>
</tr>
</table>
<hr />
</div>
<div class="sect1" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h2 class="title" style="clear: both"><a id="readmodifywrite"></a>Read/Modify/Write</h2>
</div>
</div>
</div>
<p>
If you are retrieving
<span>a record from the database or a class from the store</span>
for the purpose of modifying or deleting it, you should declare
a read-modify-write cycle at the time that you read the
<span>record.</span>
Doing so causes DB to obtain write locks (instead of a read
locks) at the time of the read. This helps to prevent deadlocks by
preventing another transaction from acquiring a read lock on the same
record while the read-modify-write cycle is in progress.
</p>
<p>
Note that declaring a read-modify-write cycle may actually increase the amount of blocking that your
application sees, because readers immediately obtain write locks and write locks cannot be shared. For this
reason, you should use read-modify-write cycles only if you are seeing a large amount of deadlocking
occurring in your application.
</p>
<p>
In order to declare a read/modify/write cycle when you perform a
read operation,
<span>
specify
<code class="classname">com.sleepycat.db.LockMode.RMW</code>
to the database, cursor,
<code class="classname">PrimaryIndex</code>, or
<code class="classname">SecondaryIndex</code> get method.
</span>
</p>
<p>
For example:
</p>
<pre class="programlisting">// Begin the deadlock retry loop as is normal.
while (retry_count < MAX_DEADLOCK_RETRIES) {
try {
txn = myEnv.beginTransaction(null, null);
...
// key and data are DatabaseEntry objects.
// Their usage is omitted for brevity.
...
// Read the data. Declare the read/modify/write cycle here
myDatabase.get(txn, key, data, LockMode.RMW);
// Put the data. Note that you do not have to provide any
// additional flags here due to the read/modify/write
// cycle. Simply put the data and perform your deadlock
// detection as normal.
myDatabase.put(txn, key, data);
txn.commit();
return 0;
} catch (DeadlockException de) {
// Deadlock detection and exception handling omitted
// for brevity
... </pre>
<p>
Or, with the DPL:
</p>
<pre class="programlisting">// Begin the deadlock retry loop as is normal
while (retry_count < MAX_DEADLOCK_RETRIES) {
try {
txn = myEnv.beginTransaction(null, null);
...
// 'store' is an EntityStore and 'Inventory' is an entity class
// Their usage and implementation is omitted for brevity.
...
// Read the data, using the PrimaryIndex for the entity object
PrimaryIndex<String,Inventory> pi =
store.getPrimaryIndex(String.class, Inventory.class);
Inventory iv = pi.get(txn, "somekey", LockMode.RMW);
// Do something to the retreived object
// Put the object. Note that you do not have to provide any
// additional flags here due to the read/modify/write
// cycle. Simply put the data and perform your deadlock
// detection as normal.
pi.put(txn, iv);
txn.commit();
return 0;
} catch (DeadlockException de) {
// Deadlock detection and exception handling omitted
// for brevity
... </pre>
</div>
<div class="navfooter">
<hr />
<table width="100%" summary="Navigation footer">
<tr>
<td width="40%" align="left"><a accesskey="p" href="exclusivelock.html">Prev</a> </td>
<td width="20%" align="center">
<a accesskey="u" href="txnconcurrency.html">Up</a>
</td>
<td width="40%" align="right"> <a accesskey="n" href="txnnowait.html">Next</a></td>
</tr>
<tr>
<td width="40%" align="left" valign="top">Exclusive Database Handles </td>
<td width="20%" align="center">
<a accesskey="h" href="index.html">Home</a>
</td>
<td width="40%" align="right" valign="top"> No Wait on Blocks</td>
</tr>
</table>
</div>
</body>
</html>
|