-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathtransactions.html
173 lines (173 loc) · 17.7 KB
/
transactions.html
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
<!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/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<title>WiredTiger: Transactions</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="navtree.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="resize.js"></script>
<script type="text/javascript" src="navtree.js"></script>
<script type="text/javascript">
$(document).ready(initResizable);
$(window).load(resizeHeight);
</script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
<link href="wiredtiger.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr style="height: 56px;">
<td id="projectlogo"><a href="http://wiredtiger.com/"><img alt="Logo" src="LogoFinal-header.png" alt="WiredTiger" /></a></td>
<td style="padding-left: 0.5em;">
<div id="projectname">
 <span id="projectnumber">Version 1.5.0</span>
</div>
</td>
</tr>
</tbody>
</table>
</div>
<div class="banner">
<a href="https://github.com/wiredtiger/wiredtiger">Fork me on GitHub</a>
<a class="last" href="http://groups.google.com/group/wiredtiger-users">Join my user group</a>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.8.3.1 -->
<div id="navrow1" class="tabs">
<ul class="tablist">
<li><a href="index.html"><span>Main Page</span></a></li>
<li class="current"><a href="pages.html"><span>Related Pages</span></a></li>
<li><a href="modules.html"><span>Modules</span></a></li>
<li><a href="examples.html"><span>Examples</span></a></li>
<li><a href="community.html"><span>Community</span></a></li>
<li><a href="license.html"><span>License</span></a></li>
</ul>
</div>
</div><!-- top -->
<div id="side-nav" class="ui-resizable side-nav-resizable">
<div id="nav-tree">
<div id="nav-tree-contents">
<div id="nav-sync" class="sync"></div>
</div>
</div>
<div id="splitbar" style="-moz-user-select:none;"
class="ui-resizable-handle">
</div>
</div>
<script type="text/javascript">
$(document).ready(function(){initNavTree('transactions.html','');});
</script>
<div id="doc-content">
<div class="header">
<div class="headertitle">
<div class="title">Transactions </div> </div>
</div><!--header-->
<div class="contents">
<div class="textblock"><h1><a class="anchor" id="transactions_acid"></a>
ACID properties</h1>
<p>Transactions provide a powerful abstraction for multiple threads to operate on data concurrently because they have the following properties:</p>
<ul>
<li>Atomicity: all or none of a transaction is completed.</li>
<li>Consistency: if each transaction maintains some property when considered separately, then the combined effect of executing the transactions concurrently will maintain the same property.</li>
<li>Isolation: developers can reason about transactions as if they run single-threaded.</li>
<li>Durability: once a transaction commits, its updates cannot be lost.</li>
</ul>
<p>WiredTiger supports transactions with the following caveats to the ACID properties:</p>
<ul>
<li>the maximum level of isolation supported is snapshot isolation. See <a class="el" href="transactions.html#transaction_isolation">Isolation levels</a> for more details.</li>
<li>only coarse-grained durability is supported: updates become durable when they are part of a checkpoint, not at commit time. If there is a crash, commits since the last checkpoint will be lost.</li>
</ul>
<h1><a class="anchor" id="transactions_api"></a>
Transactional API</h1>
<p>In WiredTiger, transaction operations are methods off the <a class="el" href="struct_w_t___s_e_s_s_i_o_n.html" title="All data operations are performed in the context of a WT_SESSION.">WT_SESSION</a> class.</p>
<p>Applications call <a class="el" href="struct_w_t___s_e_s_s_i_o_n.html#a7e26b16b26b5870498752322fad790bf" title="Start a transaction in this session.">WT_SESSION::begin_transaction</a> to start a new transaction. Operations subsequently performed using that <a class="el" href="struct_w_t___s_e_s_s_i_o_n.html" title="All data operations are performed in the context of a WT_SESSION.">WT_SESSION</a> handle, including operations on any cursors open in that <a class="el" href="struct_w_t___s_e_s_s_i_o_n.html" title="All data operations are performed in the context of a WT_SESSION.">WT_SESSION</a> handle, are part of the transaction and their effects committed by calling <a class="el" href="struct_w_t___s_e_s_s_i_o_n.html#a712226eca5ade5bd123026c624468fa2" title="Commit the current transaction.">WT_SESSION::commit_transaction</a>, or discarded by calling <a class="el" href="struct_w_t___s_e_s_s_i_o_n.html#ab45f521464ad9e54d9b15efc2ffe20a1" title="Roll back the current transaction.">WT_SESSION::rollback_transaction</a>.</p>
<p>If <a class="el" href="struct_w_t___s_e_s_s_i_o_n.html#a712226eca5ade5bd123026c624468fa2" title="Commit the current transaction.">WT_SESSION::commit_transaction</a> returns an error for any reason, the transaction was rolled-back, not committed.</p>
<p>When transactions are used, data operations can encounter a conflict and fail with the <a class="el" href="group__wt.html#ga9650b6e97a88921ec1302935908d0c47" title="Conflict between concurrent operations.">WT_DEADLOCK</a> error. If this error occurs, transactions should be rolled back with <a class="el" href="struct_w_t___s_e_s_s_i_o_n.html#ab45f521464ad9e54d9b15efc2ffe20a1" title="Roll back the current transaction.">WT_SESSION::rollback_transaction</a> and retried.</p>
<p>The <a class="el" href="struct_w_t___s_e_s_s_i_o_n.html#a7e26b16b26b5870498752322fad790bf" title="Start a transaction in this session.">WT_SESSION::begin_transaction</a>, <a class="el" href="struct_w_t___s_e_s_s_i_o_n.html#a712226eca5ade5bd123026c624468fa2" title="Commit the current transaction.">WT_SESSION::commit_transaction</a> and <a class="el" href="struct_w_t___s_e_s_s_i_o_n.html#ab45f521464ad9e54d9b15efc2ffe20a1" title="Roll back the current transaction.">WT_SESSION::rollback_transaction</a> methods all implicitly reset open cursors, as if <a class="el" href="struct_w_t___c_u_r_s_o_r.html#afc1b42c22c9c85e1ba08ce3b34437565" title="Reset the position of the cursor.">WT_CURSOR::reset</a> were called, discarding any position or key/value information they may have.</p>
<div class="fragment"><div class="line"> ret =</div>
<div class="line"> session-><a class="code" href="struct_w_t___s_e_s_s_i_o_n.html#afb5b4a69c2c5cafe411b2b04fdc1c75d" title="Open a new cursor on a data source or duplicate an existing cursor.">open_cursor</a>(session, <span class="stringliteral">"table:mytable"</span>, NULL, NULL, &cursor);</div>
<div class="line"> ret = session-><a class="code" href="struct_w_t___s_e_s_s_i_o_n.html#a7e26b16b26b5870498752322fad790bf" title="Start a transaction in this session.">begin_transaction</a>(session, NULL);</div>
<div class="line"> <span class="comment">/*</span></div>
<div class="line"><span class="comment"> * Cursors may be opened before or after the transaction begins, and in</span></div>
<div class="line"><span class="comment"> * either case, subsequent operations are included in the transaction.</span></div>
<div class="line"><span class="comment"> * The begin_transaction call resets all open cursors.</span></div>
<div class="line"><span class="comment"> */</span></div>
<div class="line"></div>
<div class="line"> cursor-><a class="code" href="struct_w_t___c_u_r_s_o_r.html#ad1088d719df40babc1f57d086691ebdc" title="Set the key for the next operation.">set_key</a>(cursor, <span class="stringliteral">"key"</span>);</div>
<div class="line"> cursor-><a class="code" href="struct_w_t___c_u_r_s_o_r.html#a27f7cbd0cd3e561f6a145704813ad64c" title="Set the value for the next operation.">set_value</a>(cursor, <span class="stringliteral">"value"</span>);</div>
<div class="line"> <span class="keywordflow">switch</span> (ret = cursor-><a class="code" href="struct_w_t___c_u_r_s_o_r.html#a444cdc0952e7f8d55d23173516c7037f" title="Update a record.">update</a>(cursor)) {</div>
<div class="line"> <span class="keywordflow">case</span> 0: <span class="comment">/* Update success */</span></div>
<div class="line"> ret = session-><a class="code" href="struct_w_t___s_e_s_s_i_o_n.html#a712226eca5ade5bd123026c624468fa2" title="Commit the current transaction.">commit_transaction</a>(session, NULL);</div>
<div class="line"> <span class="comment">/*</span></div>
<div class="line"><span class="comment"> * The commit_transaction call resets all open cursors.</span></div>
<div class="line"><span class="comment"> * If commit_transaction fails, the transaction was rolled-back.</span></div>
<div class="line"><span class="comment"> */</span></div>
<div class="line"> <span class="keywordflow">break</span>;</div>
<div class="line"> <span class="keywordflow">case</span> <a class="code" href="group__wt.html#ga9650b6e97a88921ec1302935908d0c47" title="Conflict between concurrent operations.">WT_DEADLOCK</a>: <span class="comment">/* Update conflict */</span></div>
<div class="line"> <span class="keywordflow">default</span>: <span class="comment">/* Other error */</span></div>
<div class="line"> ret = session-><a class="code" href="struct_w_t___s_e_s_s_i_o_n.html#ab45f521464ad9e54d9b15efc2ffe20a1" title="Roll back the current transaction.">rollback_transaction</a>(session, NULL);</div>
<div class="line"> <span class="comment">/* The rollback_transaction call resets all open cursors. */</span></div>
<div class="line"> <span class="keywordflow">break</span>;</div>
<div class="line"> }</div>
<div class="line"></div>
<div class="line"> <span class="comment">/* Cursors remain open and may be used for multiple transactions. */</span></div>
</div><!-- fragment --> <h1><a class="anchor" id="transactions_implicit"></a>
Implicit transactions</h1>
<p>If a cursor is used when no explicit transaction is active in a session, reads are performed at the isolation level of the session, set with the <code>isolation</code> key to <a class="el" href="struct_w_t___c_o_n_n_e_c_t_i_o_n.html#afc75c44ff4497627c59d9b6aaa64c9d8" title="Open a session.">WT_CONNECTION::open_session</a>, and successful updates are automatically committed before the update operation completes.</p>
<p>Any operation that consists of multiple related updates should be enclosed in an explicit transaction to ensure that the updates are applied atomically.</p>
<p>See <a class="el" href="cursors.html#cursors_transactions">Cursors and Transactions</a> for more information.</p>
<h1><a class="anchor" id="transactions_concurrency"></a>
Concurrency control</h1>
<p>WiredTiger uses optimistic concurrency control algorithms. This avoids the bottleneck of a centralized lock manager and ensures transactional operations do not block: reads do not block writes, and vice versa.</p>
<p>Further, writes do not block writes, although concurrent transactions updating the same value will fail with <a class="el" href="group__wt.html#ga9650b6e97a88921ec1302935908d0c47" title="Conflict between concurrent operations.">WT_DEADLOCK</a>. Some applications may benefit from application-level synchronization to avoid repeated attempts to rollback and update the same value.</p>
<p>Operations in transactions may also fail with the <a class="el" href="group__wt.html#ga9650b6e97a88921ec1302935908d0c47" title="Conflict between concurrent operations.">WT_DEADLOCK</a> error if some resource cannot be allocated after repeated attempts. For example, if the cache is not large enough to hold the updates required to satisfy transactional readers, an operation may fail and return <a class="el" href="group__wt.html#ga9650b6e97a88921ec1302935908d0c47" title="Conflict between concurrent operations.">WT_DEADLOCK</a>.</p>
<h1><a class="anchor" id="transaction_isolation"></a>
Isolation levels</h1>
<p>WiredTiger supports <code>read-uncommitted</code>, <code>read-committed</code> and <code>snapshot</code> isolation levels; the default isolation level is <code>read-committed</code>.</p>
<ul>
<li><code>read-uncommitted</code>: Transactions can see changes made by other transactions before those transactions are committed. Dirty reads, non-repeatable reads and phantoms are possible.</li>
</ul>
<ul>
<li><code>read-committed</code>: Transactions cannot see changes made by other transactions before those transactions are committed. Dirty reads are not possible; non-repeatable reads and phantoms are possible. Committed changes from concurrent transactions become visible when no cursor is positioned in the read-committed transaction.</li>
</ul>
<ul>
<li><code>snapshot</code>: Transactions read the versions of records committed before the transaction started. Dirty reads and non-repeatable reads are not possible; phantoms are possible.<br/>
<br/>
Snapshot isolation is a strong guarantee, but not equivalent to a single-threaded execution of the transactions, known as serializable isolation. Concurrent transactions T1 and T2 running under snapshot isolation may both commit and produce a state that neither (T1 followed by T2) nor (T2 followed by T1) could have produced, if there is overlap between T1's reads and T2's writes, and between T1's writes and T2's reads.</li>
</ul>
<p>The transaction isolation level can be configured on a per-transaction basis:</p>
<div class="fragment"><div class="line"> <span class="comment">/* A single transaction configured for snapshot isolation. */</span></div>
<div class="line"> ret =</div>
<div class="line"> session-><a class="code" href="struct_w_t___s_e_s_s_i_o_n.html#afb5b4a69c2c5cafe411b2b04fdc1c75d" title="Open a new cursor on a data source or duplicate an existing cursor.">open_cursor</a>(session, <span class="stringliteral">"table:mytable"</span>, NULL, NULL, &cursor);</div>
<div class="line"> ret = session-><a class="code" href="struct_w_t___s_e_s_s_i_o_n.html#a7e26b16b26b5870498752322fad790bf" title="Start a transaction in this session.">begin_transaction</a>(session, <span class="stringliteral">"isolation=snapshot"</span>);</div>
<div class="line"> cursor-><a class="code" href="struct_w_t___c_u_r_s_o_r.html#ad1088d719df40babc1f57d086691ebdc" title="Set the key for the next operation.">set_key</a>(cursor, <span class="stringliteral">"some-key"</span>);</div>
<div class="line"> cursor-><a class="code" href="struct_w_t___c_u_r_s_o_r.html#a27f7cbd0cd3e561f6a145704813ad64c" title="Set the value for the next operation.">set_value</a>(cursor, <span class="stringliteral">"some-value"</span>);</div>
<div class="line"> ret = cursor-><a class="code" href="struct_w_t___c_u_r_s_o_r.html#a444cdc0952e7f8d55d23173516c7037f" title="Update a record.">update</a>(cursor);</div>
<div class="line"> ret = session-><a class="code" href="struct_w_t___s_e_s_s_i_o_n.html#a712226eca5ade5bd123026c624468fa2" title="Commit the current transaction.">commit_transaction</a>(session, NULL);</div>
</div><!-- fragment --><p> Additionally, the default transaction isolation can be configured and re-configured on a per-session basis:</p>
<div class="fragment"><div class="line"> <span class="comment">/* Open a session configured for read-uncommitted isolation. */</span></div>
<div class="line"> ret = conn-><a class="code" href="struct_w_t___c_o_n_n_e_c_t_i_o_n.html#afc75c44ff4497627c59d9b6aaa64c9d8" title="Open a session.">open_session</a>(</div>
<div class="line"> conn, NULL, <span class="stringliteral">"isolation=read_uncommitted"</span>, &session);</div>
</div><!-- fragment --> <div class="fragment"><div class="line"> <span class="comment">/* Re-configure a session for snapshot isolation. */</span></div>
<div class="line"> ret = session-><a class="code" href="struct_w_t___s_e_s_s_i_o_n.html#a578f0fbd8a83339f1f9c00e135f006e6" title="Reconfigure a session handle.">reconfigure</a>(session, <span class="stringliteral">"isolation=snapshot"</span>);</div>
</div><!-- fragment --> <h1><a class="anchor" id="transaction_recovery"></a>
Checkpoints and Recovery</h1>
<p>Recovery is run automatically when a data source is opened. Any changes since the last checkpoint are discarded, and the application restarts from a consistent point in the transaction history.</p>
<p>This demonstrates the importance of regular checkpoints: they limit the volume of commits that may be lost in a crash. See <a class="el" href="struct_w_t___s_e_s_s_i_o_n.html#a6550c9079198955c5071583941c85bbf" title="Write a transactionally consistent snapshot of a database or set of objects.">WT_SESSION::checkpoint</a> and <a class="el" href="checkpoints.html">Checkpoints</a> for further information. </p>
</div></div><!-- contents -->
</div><!-- doc-content -->
<!-- start footer part -->
<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
<ul>
<li class="navelem"><a class="el" href="index.html">Reference Guide</a></li><li class="navelem"><a class="el" href="programming.html">Writing WiredTiger applications</a></li>
<li class="footer">Copyright (c) 2008-2013 WiredTiger, Inc. All rights reserved. Contact <a href="mailto:[email protected]">[email protected]</a> for more information.</li>
</ul>
</div>
</body>
</html>