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

Reply via email to