Add docs to the src
[frozenviper.git] / docs / google-appengine-docs-20100817 / appengine / articles / transaction_isolation.html
blob18acc8b639cc209aed83acff436db092852dcaf4
2 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
31 <html>
32 <head>
33 <script type="text/javascript" language="JavaScript">
34 ORIGINAL_PAGE_PATH = "/appengine/articles/transaction_isolation.html";
35 </script>
38 <meta http-equiv="content-type" content="text/html; charset=utf-8">
39 <title>Transaction Isolation in App Engine - Google App Engine - Google Code</title>
40 <script type="text/javascript"><!--
41 (function(){function a(){this.t={};this.tick=function(c){this.t[c]=(new Date).getTime()};this.tick("start")}var b=new a;window.jstiming={Timer:a,load:b};if(window.external&&window.external.pageT)window.jstiming.pt=window.external.pageT;})();
43 var _tocPath_ = '/appengine/docs/_toc.ezt';
44 var codesite_token = null;
45 var logged_in_user_email = null;
46 //--></script>
47 <link href="../../css/codesite.pack.04102009.css" type="text/css" rel="stylesheet">
48 <script src="../../js/codesite_head.pack.04102009.js" type="text/javascript"></script>
49 <script type="text/javascript">CODESITE_CSITimer['load'].tick('bhs');</script>
50 <link rel="search" type="application/opensearchdescription+xml" title="Google Code" href="http://code.google.com/osd.xml">
52 <!--[if IE]><link rel="stylesheet" type="text/css" href="../../css/iehacks.css"><![endif]-->
54 <link href="../../css/semantic_headers.css" rel="stylesheet" type="text/css" />
55 <link href="../css/local_extensions.css" rel="stylesheet" type="text/css" />
56 <script src="../js/customtabs.js" type="text/javascript"></script>
57 <script src="../js/ui.tabs.js" type="text/javascript"></script>
58 </head>
60 <body class="gc-documentation">
64 <div id="gb">
65 <span>
67 <a id="lang-dropdown" class="dropdown" href="http://code.google.com" onclick="return false;"><img width="13" height="13" class="globeicon" src="../../images/globe2_small.png"
68 ><span style="text-decoration:underline">English</span> <span style="font-size:.75em;">&#9660;</span></a>
70 </span>
71 </div>
73 <div class="gbh" style="left:0px;"></div>
74 <div class="gbh" style="right:0px;"></div>
76 <div id="gc-container">
77 <a id="top"></a>
78 <div id="skipto">
79 <a href="#gc-pagecontent-anchor">Skip to page content</a>
80 <a href="#gc-toc-anchor">Skip to main navigation</a>
81 </div>
83 <div id="gc-header">
84 <div id="logo"><a href="http://code.google.com">
87 <img src="../../images/code_logo.png" height="40" width="161" alt="Google Code" style="border:0;margin:3px 0 0 0;">
90 </a></div>
91 <div id="search">
92 <div id="searchForm" class="searchForm">
93 <form id="cse" action="http://www.google.com/cse" accept-charset="utf-8" class="gsc-search-box" onsubmit="executeGSearch(document.getElementById('gsearchInput').value); return false;">
94 <noscript>
95 <input type="hidden" name="cref" value="http://code.google.com/cse/googlecode-context.xml">
96 </noscript>
97 <div id="gsc-search-box">
98 <input id="gsearchInput" type="text" name="q" maxlength="2048" class="gsc-input" autocomplete="off" title="Google Code Search" style="width:345px">
99 <div id="cs-searchresults" onclick="event.cancelBubble = true;"></div>
100 <input title="Search" id="gsearchButton" class="gsc-search-button" name="sa" value="Search" type="submit">
101 <div class="greytext">e.g. "templates" or "datastore"</div>
102 </div>
103 </form>
104 </div> <!-- end searchForm -->
105 </div> <!-- end search -->
110 </div> <!-- end gc-header -->
113 <div id="codesiteContent">
115 <a id="gc-topnav-anchor"></a>
116 <div id="gc-topnav">
117 <h1 style="padding:0 0 0 6px;">Google App Engine</h1>
118 <ul id="articles" class="gc-topnav-tabs">
120 <li id="home_link">
121 <a href="../index.html" title="Google App Engine home page">Home</a>
122 </li>
124 <li id="docs_link">
125 <a href="../docs/index.html" title="Official Google App Engine documentation">Docs</a>
126 </li>
128 <li id="faq_link">
129 <a href="../kb/index.html" title="Answers to frequently asked questions about Google App Engine">FAQ</a>
130 </li>
132 <li id="articles_link">
133 <a href="index.html" class="selected" title="Focused articles and tutorials for Google App Engine developers">Articles</a>
134 </li>
136 <li>
137 <a href="http://googleappengine.blogspot.com/" title="Official Google App Engine blog">Blog</a>
138 </li>
140 <li>
141 <a href="../community.html" title="Community home for Google App Engine">Community</a>
142 </li>
144 <li>
145 <a href="../terms.html" title="Google App Engine terms of service">Terms</a>
146 </li>
148 <li>
149 <a href="../downloads.html" title="Download Google App Engine">Download</a>
150 </li>
153 </ul>
154 </div> <!-- end gc-topnav -->
156 <div class="g-section g-tpl-170">
158 <a name="gc-toc-anchor"></a>
159 <div class="g-unit g-first" id="gc-toc">
160 <ul>
161 <li><a href="../downloads.html">Downloads</a></li>
162 <li><a href="http://code.google.com/status/appengine">System Status</a></li>
163 <li><a href="http://code.google.com/p/googleappengine/issues/list">Issue Tracker</a></li>
164 <li><a href="../business/index.html">App Engine for Business</a> <sup class="new">New!</sup></li>
165 </ul>
166 <div class="line"></div>
167 <ul>
168 <li><h2>Getting Started</h2>
169 <ul>
170 <li><a href="../docs/whatisgoogleappengine.html">What Is Google App Engine?</a></li>
171 <li><a href="../docs/java/gettingstarted/index.html">Java</a>
172 <ul>
173 <li><a href="../docs/java/gettingstarted/introduction.html">Introduction</a></li>
174 <li><a href="../docs/java/gettingstarted/installing.html">Installing the Java SDK</a></li>
175 <li><a href="../docs/java/gettingstarted/creating.html">Creating a Project</a></li>
176 <li><a href="../docs/java/gettingstarted/usingusers.html">Using the Users Service</a></li>
177 <li><a href="../docs/java/gettingstarted/usingjsps.html">Using JSPs</a></li>
178 <li><a href="../docs/java/gettingstarted/usingdatastore.html">Using the Datastore with JDO</a></li>
179 <li><a href="../docs/java/gettingstarted/staticfiles.html">Using Static Files</a></li>
180 <li><a href="../docs/java/gettingstarted/uploading.html">Uploading Your Application</a></li>
182 </ul>
183 </li>
184 <li><a href="../docs/python/gettingstarted/index.html">Python</a>
185 <ul>
186 <li><a href="../docs/python/gettingstarted/introduction.html">Introduction</a></li>
187 <li><a href="../docs/python/gettingstarted/devenvironment.html">The Development Environment</a></li>
188 <li><a href="../docs/python/gettingstarted/helloworld.html">Hello, World!</a></li>
189 <li><a href="../docs/python/gettingstarted/usingwebapp.html">Using the webapp Framework</a></li>
190 <li><a href="../docs/python/gettingstarted/usingusers.html">Using the Users Service</a></li>
191 <li><a href="../docs/python/gettingstarted/handlingforms.html">Handling Forms With webapp</a></li>
192 <li><a href="../docs/python/gettingstarted/usingdatastore.html">Using the Datastore</a></li>
193 <li><a href="../docs/python/gettingstarted/templates.html">Using Templates</a></li>
194 <li><a href="../docs/python/gettingstarted/staticfiles.html">Using Static Files</a></li>
195 <li><a href="../docs/python/gettingstarted/uploading.html">Uploading Your Application</a></li>
197 </ul>
198 </li>
199 </ul>
200 </li>
201 </ul>
202 <div class="line"></div>
203 <ul>
204 <li><h2>Java</h2>
205 <ul>
206 <li><a href="../docs/java/overview.html">Overview</a></li>
207 <li><a href="../docs/java/runtime.html">Servlet Environment</a></li>
208 <li><a href="../docs/java/datastore/index.html">Storing Data</a>
209 <ul>
210 <li><a href="../docs/java/datastore/overview.html">Overview</a></li>
211 <li><a href="../docs/java/datastore/usingjdo.html">Using JDO</a></li>
212 <li><a href="../docs/java/datastore/dataclasses.html">Defining Data Classes</a></li>
213 <li><a href="../docs/java/datastore/creatinggettinganddeletingdata.html">Creating, Getting and Deleting Data</a></li>
214 <li><a href="../docs/java/datastore/queriesandindexes.html">Queries and Indexes</a></li>
215 <li><a href="../docs/java/datastore/transactions.html">Transactions</a></li>
216 <li><a href="../docs/java/datastore/relationships.html">Relationships</a></li>
217 <li><a href="../docs/java/datastore/stats.html">Statistics</a></li>
218 <li><a href="../docs/java/datastore/usingjpa.html">Using JPA</a></li>
219 <li><a href="../docs/java/javadoc/com/google/appengine/api/datastore/package-summary.html">Low-level API</a></li>
221 </ul>
222 </li>
223 <li><a href="../docs/java/apis.html">Services</a>
224 <ul>
225 <li><a href="../docs/java/blobstore/index.html">Blobstore</a>
226 <ul>
227 <li><a href="../docs/java/blobstore/overview.html">Overview</a></li>
228 <li><span class="tlw-title tlw-expanded">Reference</span>
229 <ul>
230 <li><a href="../docs/java/javadoc/com/google/appengine/api/blobstore/package-summary.html">API Reference</a></li>
231 </ul>
232 </li>
234 </ul>
235 </li>
236 <li><a href="../docs/java/images/index.html">Images</a>
237 <ul>
238 <li><a href="../docs/java/images/overview.html">Overview</a></li>
239 <li><a href="../docs/java/javadoc/com/google/appengine/api/images/package-summary.html">API Reference</a></li>
241 </ul>
242 </li>
243 <li><a href="../docs/java/mail/index.html">Mail</a>
244 <ul>
245 <li><a href="../docs/java/mail/overview.html">Overview</a></li>
246 <li><a href="../docs/java/mail/usingjavamail.html">Using JavaMail to Send Mail</a></li>
247 <li><a href="../docs/java/mail/receiving.html">Receiving Mail</a></li>
248 <li><a href="../docs/java/javadoc/com/google/appengine/api/mail/package-summary.html">Low-level API</a></li>
250 </ul>
251 </li>
252 <li><a href="../docs/java/memcache/index.html">Memcache</a>
253 <ul>
254 <li><a href="../docs/java/memcache/overview.html">Overview</a></li>
255 <li><a href="../docs/java/memcache/usingjcache.html">Using JCache</a></li>
256 <li><a href="../docs/java/javadoc/com/google/appengine/api/memcache/package-summary.html">Low-level API</a></li>
258 </ul>
259 </li>
260 <li><a href="../docs/java/multitenancy/index.html">Multitenancy</a>
261 <ul>
262 <li><a href="../docs/java/multitenancy/overview.html">Overview</a></li>
263 <li><a href="../docs/java/multitenancy/multitenancy.html">Multitenancy with Namespaces</a></li>
264 <li><a href="../docs/java/multitenancy/namespaces.html">Other Uses for Namespaces</a></li>
265 <li><a href="../docs/java/javadoc/com/google/appengine/api/NamespaceManager.html">API Reference</a>
267 </ul>
268 </li>
269 <li><a href="../docs/java/oauth/index.html">OAuth</a>
270 <ul>
271 <li><a href="../docs/java/oauth/overview.html">Overview</a></li>
272 <li><a href="../docs/java/javadoc/com/google/appengine/api/oauth/package-summary.html">API Reference</a></li>
275 </ul>
276 </li>
277 <li><a href="../docs/java/taskqueue/index.html">Task Queues</a>
278 <ul>
279 <li><a href="../docs/java/taskqueue/overview.html">Overview</a></li>
280 <li><a href="../docs/java/javadoc/com/google/appengine/api/labs/taskqueue/package-summary.html">API Reference</a></li>
282 </ul>
283 </li>
284 <li><a href="../docs/java/urlfetch/index.html">URL Fetch</a>
285 <ul>
286 <li><a href="../docs/java/urlfetch/overview.html">Overview</a></li>
287 <li><a href="../docs/java/urlfetch/usingjavanet.html">Using java.net</a></li>
288 <li><a href="../docs/java/javadoc/com/google/appengine/api/urlfetch/package-summary.html">Low-level API</a></li>
290 </ul>
291 </li>
292 <li><a href="../docs/java/users/index.html">Users</a>
293 <ul>
294 <li><a href="../docs/java/users/overview.html">Overview</a></li>
295 <li><a href="../docs/java/javadoc/com/google/appengine/api/users/package-summary.html">API Reference</a></li>
297 </ul>
298 </li>
299 <li><a href="../docs/java/xmpp/index.html">XMPP</a>
300 <ul>
301 <li><a href="../docs/java/xmpp/overview.html">Overview</a></li>
302 <li><a href="../docs/java/javadoc/com/google/appengine/api/xmpp/package-summary.html">API Reference</a></li>
304 </ul>
305 </li>
306 </ul>
307 </li>
308 <li><a href="../docs/java/javadoc/index.html">Services Javadoc</a></li>
309 <li><a href="../docs/java/jrewhitelist.html">JRE Class White List</a></li>
310 <li><a href="../docs/java/config/index.html">Configuration</a>
311 <ul>
312 <li><a href="../docs/java/config/webxml.html">Deployment Descriptor</a></li>
313 <li><a href="../docs/java/config/appconfig.html">App Config</a></li>
314 <li><a href="../docs/java/config/indexconfig.html">Index Config</a></li>
315 <li><a href="../docs/java/config/cron.html">Scheduled Tasks</a></li>
316 <li><a href="../docs/java/config/queue.html">Task Queue Config</a></li>
317 <li><a href="../docs/java/config/dos.html">DoS Protection Config</a></li>
319 </ul>
320 </li>
321 <li><a href="../docs/java/configyaml/index.html">YAML Configuration</a>
322 <ul>
323 <li><a href="../docs/java/configyaml/appconfig_yaml.html">YAML App Config</a></li>
324 <li><a href="../docs/java/configyaml/indexconfig.html">Index Config</a></li>
325 <li><a href="../docs/java/configyaml/cron.html">Scheduled Tasks</a></li>
326 <li><a href="../docs/java/configyaml/queue.html">Task Queue Config</a></li>
327 <li><a href="../docs/java/configyaml/dos.html">DoS Protection Config</a></li>
329 </ul>
330 </li>
331 <li><a href="../docs/java/tools/index.html">Tools</a>
332 <ul>
333 <li><a href="../docs/java/tools/devserver.html">Development Server</a></li>
334 <li><a href="../docs/java/tools/uploadinganapp.html">Uploading and Managing</a></li>
335 <li><a href="../docs/java/tools/eclipse.html">Google Plugin for Eclipse</a></li>
336 <li><a href="../docs/java/tools/ant.html">Using Apache Ant</a></li>
337 <li><a href="../docs/java/tools/localunittesting.html">Local Unit Testing</a>
338 <ul>
339 <li><a href="../docs/java/tools/localunittesting/javadoc/index.html">Testing Javadoc</a></li>
340 </ul>
341 </li>
342 <li><a href="../docs/java/tools/appstats.html">Appstats</a></li>
344 </ul>
345 </li>
346 <li><a href="../docs/java/howto/index.html">How-To</a>
347 <ul>
348 <li><a href="../docs/java/howto/maintenance.html">Handling Scheduled Maintenance Periods</a></li>
350 </ul>
351 </li>
353 </ul>
354 </li>
355 </ul>
356 <div class="line"></div>
357 <ul>
358 <li><h2>Python</h2>
359 <ul>
360 <li><a href="../docs/python/overview.html">Overview</a></li>
361 <li><a href="../docs/python/runtime.html">CGI Environment</a></li>
362 <li><a href="../docs/python/datastore/index.html">Storing Data</a>
363 <ul>
364 <li><a href="../docs/python/datastore/overview.html">Overview</a></li>
365 <li><a href="../docs/python/datastore/entitiesandmodels.html">Entities and Models</a></li>
366 <li><a href="../docs/python/datastore/creatinggettinganddeletingdata.html">Creating, Getting and Deleting Data</a></li>
367 <li><a href="../docs/python/datastore/keysandentitygroups.html">Keys and Entity Groups</a></li>
368 <li><a href="../docs/python/datastore/queriesandindexes.html">Queries and Indexes</a></li>
369 <li><a href="../docs/python/datastore/transactions.html">Transactions</a></li>
370 <li><a href="../docs/python/datastore/typesandpropertyclasses.html">Types and Property Classes</a></li>
371 <li><a href="../docs/python/datastore/gqlreference.html">GQL Reference</a></li>
372 <li><a href="../docs/python/datastore/stats.html">Statistics</a></li>
374 <li><span class="tlw-title tlw-expanded">Reference</span>
375 <ul>
376 <li><a href="../docs/python/datastore/modelclass.html">Model</a></li>
377 <li><a href="../docs/python/datastore/expandoclass.html">Expando</a></li>
378 <li><a href="../docs/python/datastore/polymodelclass.html">PolyModel</a></li>
379 <li><a href="../docs/python/datastore/propertyclass.html">Property</a></li>
380 <li><a href="../docs/python/datastore/queryclass.html">Query</a></li>
381 <li><a href="../docs/python/datastore/gqlqueryclass.html">GqlQuery</a></li>
382 <li><a href="../docs/python/datastore/keyclass.html">Key</a></li>
383 <li><a href="../docs/python/datastore/functions.html">Functions</a></li>
384 <li><a href="../docs/python/datastore/exceptions.html">Exceptions</a></li>
385 </ul>
386 </li>
388 </ul>
389 </li>
390 <li><a href="../docs/python/apis.html">Services</a>
391 <ul>
392 <li><a href="../docs/python/blobstore/index.html">Blobstore</a>
393 <ul>
394 <li><a href="../docs/python/blobstore/overview.html">Overview</a></li>
395 <li><span class="tlw-title tlw-expanded">Reference</span>
396 <ul>
397 <li><a href="../docs/python/blobstore/blobinfoclass.html">BlobInfo</a></li>
398 <li><a href="../docs/python/blobstore/blobkeyclass.html">BlobKey</a></li>
399 <li><a href="../docs/python/blobstore/blobreaderclass.html">BlobReader</a></li>
400 <li><a href="../docs/python/blobstore/functions.html">Functions</a></li>
401 <li><a href="../docs/python/blobstore/exceptions.html">Exceptions</a></li>
402 </ul>
403 </li>
405 </ul>
406 </li>
407 <li><a href="../docs/python/images/index.html">Images</a>
408 <ul>
409 <li><a href="../docs/python/images/overview.html">Overview</a></li>
410 <li><a href="../docs/python/images/installingPIL.html">Installing PIL</a></li>
411 <li><a href="../docs/python/images/usingimages.html">Using the Images API</a></li>
412 <li><span class="tlw-title tlw-expanded">Reference</span>
413 <ul>
414 <li><a href="../docs/python/images/imageclass.html">Image</a></li>
415 <li><a href="../docs/python/images/functions.html">Functions</a></li>
416 <li><a href="../docs/python/images/exceptions.html">Exceptions</a></li>
417 </ul>
418 </li>
420 </ul>
421 </li>
422 <li><a href="../docs/python/mail/index.html">Mail</a>
423 <ul>
424 <li><a href="../docs/python/mail/overview.html">Overview</a></li>
425 <li><a href="../docs/python/mail/sendingmail.html">Sending Mail</a></li>
426 <li><a href="../docs/python/mail/receivingmail.html">Receiving Mail</a></li>
427 <li><a href="../docs/python/mail/attachments.html">Attachments</a></li>
428 <li><span class="tlw-title tlw-expanded">Reference</span>
429 <ul>
430 <li><a href="../docs/python/mail/emailmessageclass.html">EmailMessage</a></li>
431 <li><a href="../docs/python/mail/emailmessagefields.html">Message Fields</a></li>
432 <li><a href="../docs/python/mail/functions.html">Functions</a></li>
433 <li><a href="../docs/python/mail/exceptions.html">Exceptions</a></li>
434 </ul>
435 </li>
437 </ul>
438 </li>
439 <li><a href="../docs/python/memcache/index.html">Memcache</a>
440 <ul>
441 <li><a href="../docs/python/memcache/overview.html">Overview</a></li>
442 <li><a href="../docs/python/memcache/usingmemcache.html">Using Memcache</a></li>
443 <li><span class="tlw-title tlw-expanded">Reference</span>
444 <ul>
445 <li><a href="../docs/python/memcache/clientclass.html">Client</a></li>
446 <li><a href="../docs/python/memcache/functions.html">Functions</a></li>
447 </ul>
448 </li>
450 </ul>
451 </li>
452 <li><a href="../docs/python/multitenancy/index.html">Multitenancy</a>
453 <ul>
454 <li><a href="../docs/python/multitenancy/overview.html">Overview</a></li>
455 <li><a href="../docs/python/multitenancy/multitenancy.html">Multitenancy with Namespaces</a></li>
456 <li><a href="../docs/python/multitenancy/namespaces.html">Other Uses for Namespaces</a></li>
457 <li>Reference
458 <ul>
459 <li><a href="../docs/python/multitenancy/functions.html">Functions</a></li>
460 <li><a href="../docs/python/multitenancy/exceptions.html">Exceptions</a></li>
461 </ul>
462 </li>
464 </ul>
465 </li>
466 <li><a href="../docs/python/oauth/index.html">OAuth</a>
467 <ul>
468 <li><a href="../docs/python/oauth/overview.html">Overview</a></li>
469 <li><span class="tlw-title tlw-expanded">Reference</span>
470 <ul>
471 <li><a href="../docs/python/oauth/functions.html">Functions</a></li>
472 <li><a href="../docs/python/oauth/exceptions.html">Exceptions</a></li>
473 </ul>
474 </li>
476 </ul>
477 </li>
478 <li><a href="../docs/python/taskqueue/index.html">Task Queues</a>
479 <ul>
480 <li><a href="../docs/python/taskqueue/overview.html">Overview</a></li>
481 <li><span class="tlw-title tlw-expanded">Reference</span>
482 <ul>
483 <li><a href="../docs/python/taskqueue/tasks.html">Task Class</a></li>
484 <li><a href="../docs/python/taskqueue/queues.html">Queue Class</a></li>
485 <li><a href="../docs/python/taskqueue/functions.html">Functions</a></li>
486 <li><a href="../docs/python/taskqueue/exceptions.html">Exceptions</a></li>
487 </ul>
488 </li>
490 </ul>
491 </li>
492 <li><a href="../docs/python/urlfetch/index.html">URL Fetch</a>
493 <ul>
494 <li><a href="../docs/python/urlfetch/overview.html">Overview</a></li>
495 <li><span class="tlw-title tlw-expanded">Reference</span>
496 <ul>
497 <li><a href="../docs/python/urlfetch/fetchfunction.html">The fetch Function</a></li>
498 <li><a href="../docs/python/urlfetch/asynchronousrequests.html">Asynchronous Requests</a></li>
499 <li><a href="../docs/python/urlfetch/responseobjects.html">Response Objects</a></li>
500 <li><a href="../docs/python/urlfetch/exceptions.html">Exceptions</a></li>
501 </ul>
502 </li>
504 </ul>
505 </li>
506 <li><a href="../docs/python/users/index.html">Users</a>
507 <ul>
508 <li><a href="../docs/python/users/overview.html">Overview</a></li>
509 <li><a href="../docs/python/users/userobjects.html">User Objects</a></li>
510 <li><a href="../docs/python/users/loginurls.html">Login URLs</a></li>
511 <li><a href="../docs/python/users/adminusers.html">Admin Users</a></li>
513 <li><span class="tlw-title tlw-expanded">Reference</span>
514 <ul>
515 <li><a href="../docs/python/users/userclass.html">User</a></li>
516 <li><a href="../docs/python/users/functions.html">Functions</a></li>
517 <li><a href="../docs/python/users/exceptions.html">Exceptions</a></li>
518 </ul>
519 </li>
521 </ul>
522 </li>
523 <li><a href="../docs/python/xmpp/index.html">XMPP</a>
524 <ul>
525 <li><a href="../docs/python/xmpp/overview.html">Overview</a></li>
526 <li><span class="tlw-title tlw-expanded">Reference</span>
527 <ul>
528 <li><a href="../docs/python/xmpp/functions.html">Functions</a></li>
529 <li><a href="../docs/python/xmpp/messageclass.html">Message</a></li>
530 <li><a href="../docs/python/xmpp/exceptions.html">Exceptions</a></li>
531 </ul>
532 </li>
534 </ul>
535 </li>
536 </ul>
537 </li>
538 <li><a href="../docs/python/config/index.html">Configuration</a>
539 <ul>
540 <li><a href="../docs/python/config/appconfig.html">App Config</a></li>
541 <li><a href="../docs/python/config/indexconfig.html">Index Config</a></li>
542 <li><a href="../docs/python/config/cron.html">Scheduled Tasks</a></li>
543 <li><a href="../docs/python/config/queue.html">Task Queue Config</a></li>
544 <li><a href="../docs/python/config/dos.html">DoS Protection Config</a></li>
546 </ul>
547 </li>
548 <li><a href="../docs/python/tools/index.html">Tools</a>
549 <ul>
550 <li><a href="../docs/python/tools/devserver.html">Development Server</a></li>
551 <li><a href="../docs/python/tools/uploadinganapp.html">Uploading and Managing</a></li>
552 <li><a href="../docs/python/tools/uploadingdata.html">Uploading and Downloading Data</a></li>
553 <li><a href="../docs/python/tools/webapp/index.html">webapp Framework</a>
554 <ul>
555 <li><a href="../docs/python/tools/webapp/overview.html">Overview</a></li>
556 <li><a href="../docs/python/tools/webapp/running.html">Running the Application</a></li>
557 <li><a href="../docs/python/tools/webapp/requesthandlers.html">Request Handlers</a></li>
558 <li><a href="../docs/python/tools/webapp/requestdata.html">Request Data</a></li>
559 <li><a href="../docs/python/tools/webapp/buildingtheresponse.html">Building the Response</a></li>
560 <li><a href="../docs/python/tools/webapp/redirects.html">Redirects, Headers and Status Codes</a></li>
561 <li><a href="../docs/python/tools/webapp/blobstorehandlers.html">Blobstore Handlers</a></li>
563 <li><span class="tlw-title tlw-expanded">Reference</span>
564 <ul>
565 <li><a href="../docs/python/tools/webapp/requestclass.html">Request</a></li>
566 <li><a href="../docs/python/tools/webapp/responseclass.html">Response</a></li>
567 <li><a href="../docs/python/tools/webapp/requesthandlerclass.html">RequestHandler</a></li>
568 <li><a href="../docs/python/tools/webapp/wsgiapplicationclass.html">WSGIApplication</a></li>
569 <li><a href="../docs/python/tools/webapp/utilmodule.html">Utility Functions</a></li>
571 </ul>
572 </li>
574 </ul>
575 </li>
576 <li><a href="../docs/python/tools/appstats.html">Appstats</a></li>
577 <li><a href="../docs/python/tools/libraries.html">Third-party Libraries</a></li>
579 </ul>
580 </li>
581 <li><a href="../docs/python/howto/index.html">How-To</a>
582 <ul>
583 <li><a href="../docs/python/howto/usinggdataservices.html">Google Data Services</a></li>
584 <li><a href="../docs/python/howto/maintenance.html">Handling Scheduled Maintenance Periods</a></li>
586 </ul>
587 </li>
589 </ul>
590 </li>
591 </ul>
592 <div class="line"></div>
593 <ul>
594 <li><h2>Managing Your App</h2>
595 <ul>
596 <li><a href="../docs/theadminconsole.html">The Admin Console</a></li>
597 <li><a href="../docs/quotas.html">Quotas</a></li>
598 <li><a href="../docs/billing.html">Billing</a></li>
599 <li><a href="../docs/domain.html">Using a Custom Domain</a></li>
600 </ul>
601 </li>
602 </ul>
603 <div class="line"></div>
604 <ul>
605 <li><h2>Resources</h2>
606 <ul>
607 <li><a href="../kb/index.html">FAQ</a></li>
608 <li><a href="index.html">Articles</a></li>
609 <li><a href="http://appengine-cookbook.appspot.com/">Cookbook</a></li>
610 <li><a href="http://appgallery.appspot.com/">App Gallery</a></li>
611 <li><a href="http://code.google.com/p/googleappengine/">SDK Code</a></li>
612 <li><a href="http://code.google.com/p/datanucleus-appengine/">JDO/JPA Code</a></li>
613 <li><a href="http://code.google.com/p/google-app-engine-samples/">Sample Apps Code</a></li>
614 <li>Launcher Code
615 <ul>
616 <li><a href="http://code.google.com/p/google-appengine-mac-launcher/">Mac</a></li>
617 <li><a href="http://code.google.com/p/google-appengine-wx-launcher/">Windows/wx</a></li>
618 </ul>
619 </li>
620 <li><a href="../community.html">Discussion Groups</a></li>
621 </ul>
622 </li>
623 </ul>
624 <div class="line"></div>
625 <ul>
626 <li><a href="../docs/roadmap.html">Product Roadmap</a></li>
627 <li><a href="http://code.google.com/p/googleappengine/wiki/SdkReleaseNotes">Release Notes: Python</a></li>
628 <li><a href="http://code.google.com/p/googleappengine/wiki/SdkForJavaReleaseNotes">Release Notes: Java</a></li>
629 <li><a href="../docs/revision_history.html">Revision History</a></li>
630 </ul>
632 <a class="hidden" href="#gc-topnav-anchor">More Google App Engine resource links</a>
633 </div>
635 <a name="gc-pagecontent-anchor"></a>
636 <div class="g-unit" id="gc-pagecontent">
637 <script type="text/javascript">CODESITE_docEarlyProcessing();</script>
638 <h1 class="page_title">Transaction Isolation in App Engine</h1>
641 <i>Max Ross, Software Engineer</i><br>
642 <i>May 13, 2008</i>
643 <i>Revised May 2009</i>
645 <div id="jd-content">
646 <div class="jd-descr">
648 <p class="note" align="center">This is one of a <a href="datastore/overview.html">series</a> of in-depth articles discussing App Engine's datastore. To see the other articles in the series, see <a href="#related">Related links</a>.</p>
650 <p>According to <a href="http://en.wikipedia.org/w/index.php?title=Isolation_%28database_systems%29&oldid=208946883">Wikipedia</a>,
651 the isolation level of a database management system "defines how/when the
652 changes made by one operation become visible to other concurrent operations."
653 The goal of this article is to explain
654 <a href="../docs/python/datastore/queriesandindexes.html">query</a> and
655 <a href="../docs/python/datastore/transactions.html">transaction</a>
656 isolation in the Google App Engine Datastore. After reading this article
657 you should have a better understanding of how concurrent reads and writes
658 behave, both in and out of transactions.</p>
660 <h2>Inside transactions: Serializable</h2>
661 <p>In order from strongest to weakest, the four isolation levels are
662 Serializable, Repeatable Read, Read Committed, and Read Uncommitted. Datastore
663 transactions satisfy the Serializable isolation level. Each transaction is
664 completely isolated from all other datastore transactions and operations.
665 Transactions on a given entity group are executed serially, one after
666 another.</p>
668 <p>Furthermore, queries and <code>get()</code>s inside transactions see a
669 single, consistent snapshot of the datastore that lasts for the duration of
670 the transaction. See the
671 <a href="../docs/python/datastore/transactions.html#Isolation_and_Consistency">Isolation
672 and Consistency</a>
673 section of the transaction documentation for more information, as well as
674 <a href="http://en.wikipedia.org/wiki/Snapshot_isolation">Wikipedia's snapshot
675 isolation article</a>.</p>
677 <h2>Outside transactions: Read Committed</h2>
678 <p>Datastore operations <i>outside</i> transactions most closely resemble the
679 Read Committed isolation level. Entities retrieved from the datastore by
680 queries or <code>get()</code>s will consist only of committed data. A
681 retrieved entity will never have partially committed data, ie some from before
682 a commit and some from after. The interaction between queries and transactions
683 is a bit more subtle, though, and in order to understand it we need to look at
684 the <code>commit()</code> process in more depth.</p>
686 <h2>The commit() process</h2>
687 <p>A <code>commit()</code> consists of two milestones - the point at which changes to an
688 entity have been applied and the point at which changes to indices for that
689 entity have been applied. Let's call the first point Milestone A, and the
690 second point, when <code>commit()</code> returns, Milestone B. By the time we reach
691 Milestone A, all changes to the entity have been applied. By the time we
692 reach Milestone B, the changes to the entity's indices have been applied.</p>
693 <br><br>
695 <img src="transaction_iso.png"/>
697 <p>A request that looks up an updated entity by its key at a time after
698 Milestone A is guaranteed to see the latest version of that entity.
699 However, if a concurrent request executes a query whose predicate
700 (the 'where clause' for you SQL/GQL fans out there) is not satisfied
701 by the pre-update entity but is satisfied by the post-update entity,
702 the entity will only be part of the result set if the query executes
703 after the <code>commit()</code> operation has reached Milestone B. In other words,
704 during brief windows it is possible for a result set to not include an
705 entity whose properties, according to the result of a lookup by key,
706 satisfy the query predicate, and it is also possible for a result set
707 to include an entity whose properties, again according to the result
708 of a lookup by key, fail to satisfy the query predicate. Note that
709 while a query cannot take into account modifications that are in between
710 Milestone A and Milestone B when deciding which entities to return,
711 once a query decides to return a specific entity it will always return
712 the Milestone A version of the entity.</p>
715 <h2>Examples</h2>
716 <p>We've provided a general explanation of how concurrent updates and queries
717 interact, but if you're like me you typically find it easier to get your
718 head around these concepts by working through concrete examples. Let's
719 walk through a few. We'll start with some simple examples and then
720 finish up with the more interesting ones.</p>
722 <p>Let's say we have an application that stores Person entities. A Person
723 has the following attributes:</p>
724 <ul>
725 <li>Name</li>
726 <li>Height</li>
727 </ul>
729 <p>This application supports the following operations:</p>
730 <ul>
731 <li><code>updatePerson()</code></li>
732 <li><code>getTallPeople()</code>, which returns all people over 72 inches tall.</li>
733 </ul>
735 <p>We have 2 Person entities in the datastore:</p>
736 <ul>
737 <li>Adam, who is 68 inches tall.</li>
738 <li>Bob, who is 73 inches tall.</li>
739 </ul>
741 <h2>Example 1 - Making Adam Taller</h2>
742 <p>Suppose an application receives two requests at essentially the same time.
743 The first request updates the height of Adam from 68 inches to 74 inches.
744 A growth spurt! The second request calls getTallPeople().
745 What does getTallPeople() return?</p>
747 <p>The answer depends on the relationship between the two commit() milestones
748 triggered by Request 1 and the getTallPeople() query executed by Request 2.
749 Suppose it looks like this:</p>
750 <ul>
751 <li>Request 1, <code>put()</code></li>
752 <li>Request 2, <code>getTallPeople()</code></li>
753 <li>Request 1, <code>put()</code>--><code>commit()</code></li>
754 <li>Request 1, <code>put()</code>--><code>commit()</code>-->Milestone A</li>
755 <li>Request 1, <code>put()</code>--><code>commit()</code>-->Milestone B</li>
756 </ul>
758 <p>In this scenario <code>getTallPeople()</code> will only return Bob. Why? Because the
759 update to Adam that increases his height has not yet been committed, so
760 the change is not yet visible to the query we issue in Request 2.</p>
762 <p>Now suppose it looks like this:</p>
763 <ul>
764 <li>Request 1, <code>put()</code></li>
765 <li>Request 1, <code>put()</code>--><code>commit()</code></li>
766 <li>Request 1, <code>put()</code>--><code>commit()</code>-->Milestone A</li>
767 <li>Request 2, <code>getTallPeople()</code></code></li>
768 <li>Request 1, <code>put()</code>--><code>commit()</code>-->Milestone B</li>
769 </ul>
771 <p>In this scenario the query executes before Request 1 reaches Milestone B,
772 so the updates to the Person indices have not yet been applied. As a result,
773 getTallPeople() only returns Bob. This is an example of a result set that
774 excludes an entity whose properties satisfy the query predicate.</p>
776 <h2>Example 2 - Making Bob Smaller (sorry Bob)</h2>
777 <p>In this example we'll have Request 1 do something different. Instead of
778 increasing Adam's height from 68 inches to 74 inches, it will reduce Bob's
779 height from 73 inches to 65 inches. Once again, what does
780 <code>getTallPeople()</code></p>
782 <ul>
783 <li>Request 1, <code>put()</code></li>
784 <li>Request 2, <code>getTallPeople()</code></li>
785 <li>Request 1, <code>put()</code>--><code>commit()</code></li>
786 <li>Request 1, <code>put()</code>--><code>commit()</code>-->Milestone A</li>
787 <li>Request 1, <code>put()</code>--><code>commit()</code>-->Milestone B</li>
788 </ul>
790 <p>In this scenario <code>getTallPeople()</code> will return only Bob. Why? Because
791 the update to Bob that decreases his height has not yet been committed,
792 so the change is not yet visible to the query we issue in Request 2.</p>
794 <p>Now suppose it looks like this:</p>
795 <ul>
796 <li>Request 1, <code>put()</code></li>
797 <li>Request 1, <code>put()</code>--><code>commit()</code></li>
798 <li>Request 1, <code>put()</code>--><code>commit()</code>-->Milestone A</li>
799 <li>Request 1, <code>put()</code>--><code>commit()</code>-->Milestone B</li>
800 <li>Request 2, <code>getTallPeople()</code></li>
801 </ul>
804 In this scenario <code>getTallPeople()</code> will return no one. Why? Because the
805 update to Bob that decreases his height has been committed by the time
806 we issue our query in Request 2.</p>
808 <p>Now suppose it looks like this:</p>
809 <ul>
810 <li>Request 1, <code>put()</code></li>
811 <li>Request 1, <code>put()</code>--><code>commit()</code></li>
812 <li>Request 1, <code>put()</code>--><code>commit()</code>-->Milestone A</li>
813 <li>Request 2, <code>getTallPeople()</code></li>
814 <li>Request 1, <code>put()</code>--><code>commit()</code>-->Milestone B</li>
815 </ul>
817 <p>In this scenario the query executes before Milestone B, so the updates
818 to the Person indices have not yet been applied. As a result,
819 <code>getTallPeople()</code> still returns Bob, but the height property of the Person
820 entity that comes back is the updated value: 65. This is an example of
821 a result set that includes an entity whose properties fail to satisfy
822 the query predicate.</p>
824 <h2>Conclusion</h2>
825 <p>As you can see from the above examples, the transaction isolation level
826 of the Google App Engine Datastore is pretty close to Read Committed.
827 There are of course meaningful differences, but now that you understand
828 these differences and the reasons behind them you should be in a better
829 position to make intelligent, datastore-related design decisions in your
830 applications.</p>
832 <h2 id="related">Related links</h2>
834 <ul>
835 <li><a href="datastore/overview.html">Series Overview</a></li>
836 <li><a href="life_of_write.html">Life of a Datastore Write</a></li>
837 <li><a href="transaction_isolation.html">Transaction Isolation in App Engine</a></li>
838 <li><a href="index_building.html">How Index Building Works</a></li>
839 <li><a href="storage_breakdown.html">How Entities and Indexes are Stored</a></li>
840 <li><a href="modeling.html">Modeling Entity Relationships</a></li>
841 <li><a href="update_schema.html">Updating Your Model's Schema</a></li>
842 <li><a href="handling_datastore_errors.html">Handling Datastore Errors</a></li>
843 </ul>
846 </div>
847 </div>
851 </div><!-- end gc-pagecontent -->
852 </div><!-- end gooey wrapper -->
854 </div> <!-- end codesite content -->
857 <div id="gc-footer" dir="ltr">
858 <div class="text">
860 <div class="notice"><div id="notice" style="text-align: center; border: 1em 0em 1em 0em">
861 Except as otherwise <a
862 href="http://code.google.com/policies.html#restrictions">noted</a>,
863 the content of this page is licensed under the <a rel="license"
864 href="http://creativecommons.org/licenses/by/3.0/">Creative Commons
865 Attribution 3.0 License</a>, and code samples are licensed under the
866 <a rel="license" href="http://www.apache.org/licenses/LICENSE-2.0">Apache
867 2.0 License</a>.
868 <!-- <rdf:RDF xmlns="http://web.resource.org/cc/"
869 xmlns:dc="http://purl.org/dc/elements/1.1/"
870 xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
871 <Work rdf:about="">
872 <license rdf:resource="http://creativecommons.org/licenses/by/3.0/" />
873 </Work>
874 <License rdf:about="http://creativecommons.org/licenses/by/3.0/">
875 <permits rdf:resource="http://web.resource.org/cc/Reproduction"/>
876 <permits rdf:resource="http://web.resource.org/cc/Distribution"/>
877 <requires rdf:resource="http://web.resource.org/cc/Notice"/>
878 <requires rdf:resource="http://web.resource.org/cc/Attribution"/>
879 <permits rdf:resource="http://web.resource.org/cc/DerivativeWorks"/>
880 </License>
881 </rdf:RDF> -->
882 </div>
883 Java is a registered trademark of Sun Microsystems, Inc.</div>
885 &copy;2010 Google -
886 <a href="http://code.google.com">Code Home</a> -
887 <a href="http://code.google.com/terms.html">Terms of Service</a> -
888 <a href="http://code.google.com/privacy.html">Privacy Policy</a> -
889 <a href="http://code.google.com/more">Site Directory</a>
890 <br> <br>
891 Google Code offered in:
892 <a href="http://code.google.com/intl/en">English</a> -
893 <a href="http://code.google.com/intl/es">Español</a> -
894 <a href="http://code.google.com/intl/ja">日本語</a> -
895 <a href="http://code.google.com/intl/ko">한국어</a> -
896 <a href="http://code.google.com/intl/pt-BR">Português</a> -
897 <a href="http://code.google.com/intl/ru">Pусский</a> -
898 <a href="http://code.google.com/intl/zh-CN">中文(简体)</a> -
899 <a href="http://code.google.com/intl/zh-TW">中文(繁體)</a>
900 </div>
901 </div><!-- end gc-footer -->
903 </div><!-- end gc-container -->
905 <script type="text/javascript">CODESITE_CSITimer['load'].tick('ats');</script>
906 <script src="../../js/codesite_tail.pack.04102009.js" type="text/javascript"></script>
911 <script type="text/javascript">
912 var _gaq = _gaq || [];
914 _gaq.push(
917 ['siteTracker._setAccount', 'UA-18071-1'],
918 ['siteTracker._setDomainName', 'code.google.com'],
919 ['siteTracker._setCookiePath', window.location.pathname.substring(0,
920 window.location.pathname.lastIndexOf('/') + 1)],
921 ['siteTracker._trackPageview']
923 (function() {
924 var ga = document.createElement('script');
926 ga.type = 'text/javascript';
927 ga.async = true;
928 ga.src = 'http://www.google-analytics.com/ga.js';
929 (document.getElementsByTagName('head')[0] ||
930 document.getElementsByTagName('body')[0]).appendChild(ga);
931 })();
932 </script>
937 </body>
938 </html>