Author: wyoung
Date: Sat Oct 27 07:46:28 2007
New Revision: 1798
URL: http://svn.gna.org/viewcvs/mysqlpp?rev=1798&view=rev
Log:
Expanded tutorial section on transactions to include the new deadlock
example and a discussion of it.
Modified:
trunk/doc/userman/Makefile
trunk/doc/userman/userman.dbx
Modified: trunk/doc/userman/Makefile
URL:
http://svn.gna.org/viewcvs/mysqlpp/trunk/doc/userman/Makefile?rev=1798&r1=1797&r2=1798&view=diff
==============================================================================
--- trunk/doc/userman/Makefile (original)
+++ trunk/doc/userman/Makefile Sat Oct 27 07:46:28 2007
@@ -18,9 +18,9 @@
FO_SS=fo.xsl
HTML_SS=html.xsl
EX_TXT=cgi_jpeg.txt custom1.txt custom2.txt custom3.txt custom4.txt \
- custom5.txt custom6.txt fieldinf1.txt for_each.txt
load_jpeg.txt \
- resetdb.txt simple1.txt simple2.txt simple3.txt stock.txt \
- store_if.txt tquery1.txt xaction.txt
+ custom5.txt custom6.txt deadlock.txt fieldinf1.txt for_each.txt
\
+ load_jpeg.txt resetdb.txt simple1.txt simple2.txt simple3.txt \
+ stock.txt store_if.txt tquery1.txt transaction.txt
## ------------------------
Modified: trunk/doc/userman/userman.dbx
URL:
http://svn.gna.org/viewcvs/mysqlpp/trunk/doc/userman/userman.dbx?rev=1798&r1=1797&r2=1798&view=diff
==============================================================================
--- trunk/doc/userman/userman.dbx (original)
+++ trunk/doc/userman/userman.dbx Sat Oct 27 07:46:28 2007
@@ -808,7 +808,7 @@
<sect2>
- <title>Creating Transaction Sets</title>
+ <title>Using Transactions</title>
<para>MySQL++ v2.1 added the <ulink type="classref"
url="Transaction"/> class, which makes it easier to use
@@ -824,11 +824,69 @@
exception after the transaction is started but before it is
committed, the transaction isn't left unresolved.</para>
- <para><filename>examples/xaction.cpp</filename> illustrates
+ <para><filename>examples/transaction.cpp</filename> illustrates
this:</para>
- <programlisting><xi:include href="xaction.txt" parse="text"
+ <programlisting><xi:include href="transaction.txt" parse="text"
xmlns:xi="http://www.w3.org/2001/XInclude"/></programlisting>
+
+ <para>One of the downsides of transactions is that the locking
+ it requires in the database server is prone to deadlocks. The
+ classic case where this happens is when two programs both want
+ access to the same two records within a single transaction
+ each, but they modify them in opposite orders. If the timing
+ is such that the programs interleave their lock acquisitions,
+ the two come to an impasse: neither can get access to the
+ other record they want to modify until the other program
+ commits its transaction and thus release the record locks,
+ but neither can finish the transaction because they're waiting
+ on row locks the database server is holding on behalf of the
+ other program.</para>
+
+ <para>Fortunately, the MySQL server is smart enough to
+ detect this condition. The best it can do is abort the second
+ transaction. This breaks the impasse, so the first program
+ can complete its transaction.</para>
+
+ <para>The second program now has to deal with the fact that its
+ transaction just got aborted. There's a subtlety in detecting
+ this situation when using MySQL++. By default, MySQL++ signals
+ errors like these with exceptions. In the exception handler,
+ you might expect to get <constant>ER_LOCK_DEADLOCK</constant>
+ from <methodname>Connection::errnum()</methodname>, but
+ what you'll almost certainly get instead is 0, meaning
+ "no error." Why? It's because you're probably using a
+ <classname>Transaction</classname> object to get automatic
+ roll-backs in the face of exceptions. In this case, the
+ roll-back happens before your exception handler is called by
+ issuing a <command>ROLLBACK</command> query to the database
+ server. Thus, <methodname>Connection::errnum()</methodname>
+ returns the error code associated with this roll-back
+ query, not the deadlocked transaction that caused the
+ exception.</para>
+
+ <para>To avoid this problem, a few of the exception objects
+ as of MySQL++ v3.0 include this last error number in the
+ exception object itself. It's populated at the point of the
+ exception, so it can differ from the value you would get from
+ <methodname>Connection::errnum()</methodname> later on when
+ the exception handler runs.</para>
+
+ <para>The example <filename>examples/deadlock.cpp</filename>
+ demonstrates the problem:</para>
+
+ <programlisting><xi:include href="deadlock.txt" parse="text"
+ xmlns:xi="http://www.w3.org/2001/XInclude"/></programlisting>
+
+ <para>This example works a little differently than the others.
+ You run one copy of the example, then when it pauses waiting
+ for you to press <keycap>Enter</keycap>, you run another copy.
+ Then, depending on which one you press <keycap>Enter</keycap>
+ in, one of the two will abort with the deadlock exception. You
+ can see from the error message you get that it matters which
+ method you call to get the error number. What you do about
+ it is up to you as it depends on your program's design and
+ system architecture.</para>
</sect2>
_______________________________________________
Mysqlpp-commits mailing list
[email protected]
https://mail.gna.org/listinfo/mysqlpp-commits