Can anyone help? I'm trying to implement a transaction (using InnoDB tables ) in which everything done in it can be rolled back at any stage. There are several operations involved and I need to be able to undo all the work done so far at any point.
In my code below, I've deliberately set the variable I use to check whether to go on with the transaction so that everything should get rolled back. However, only the last operation ( an INSERT ) gets rolled back. Please, is that MySQL's default behaviour or am I doing something wrong? <? include("transactions.inc"); function PlaceOrder($MerchantName,$WalletID,$CartContents) { if(is_array($CartContents) && sizeof($CartContents)>0){ ConnectDBServer(); $DBName=MerchantDB($MerchantName); $i=1; $SQLQuery=" SELECT id,name,description,price FROM products WHERE id IN("; foreach($CartContents as $CartItem){ if(is_array($CartItem)){ if($i!=1) $SQLQuery.=","; $SQLQuery.=$CartItem["pid"]; $i++; } } $SQLQuery.=")"; //print $SQLQuery."<br>"; //exit; if($i>0){ $Products=array(); $result=mysql_db_query("$DBName",$SQLQuery); while($row=mysql_fetch_array($result)){ $Products[$row["id"]]=array("name"=>$row["name"], "description"=>$row["description"], "price"=>$row["price"]); } mysql_free_result($result); } else return 'Items in cart are not recognizable!'; // Calculate cost of items in shopping cart $TotalCost=0; foreach($CartContents as $CartItem){ $price=$Products[$CartItem["pid"]]["price"]; $qty=(int) $CartItem["qty"]; $TotalCost+=$price*$qty; } /* // Get current value in Wallet $SQLQuery="SELECT value FROM wallets WHERE id=$WalletID"; // LOCK IN SHARE MODE //print $SQLQuery."<br>"; //exit; $result=mysql_db_query("paymentsystem",$SQLQuery); $CurrentValue=mysql_result($result,0); mysql_free_result($result); if($TotalCost<=$CurrentValue){ */ $SQLQuery="SELECT id FROM merchants WHERE name='$MerchantName'"; $result=mysql_db_query("paymentsystem",$SQLQuery); $MerchantID=mysql_result($result,0,"id"); mysql_free_result($result); mysql_select_db("$DBName"); // --------------------- TRANSACTION STARTS HERE ----------------------------------- mysql_query("set autocommit=0"); // function I embedded the payment in before //$PaymentID=PaymentTransaction($WalletID,$MerchantID,$TotalCost); // code I used to replace the function call $Amount=$TotalCost; @mysql_select_db("paymentsystem"); if(is_Wallet($WalletID)){ if(is_Merchant($MerchantID)){ if(is_numeric($Amount)){ //mysql_query("set autocommit=0"); // from,to and amount are valid $SQLQuery=" UPDATE wallets SET value=value-$Amount WHERE id=$WalletID AND value>=$Amount"; $DebitSucceeded=@mysql_query($SQLQuery); if($DebitSucceeded){ $SQLQuery=" INSERT INTO payments(value,paymentdate,merchantid,walletid) VALUES($Amount,NOW(),$MerchantID,$WalletID)"; $RecordSucceeded=@mysql_query($SQLQuery); $PaymentID=@mysql_insert_id(); if($RecordSucceeded) mysql_query("COMMIT"); else mysql_query("ROLLBACK"); } else mysql_query("ROLLBACK"); } } } // --- code to replace function call ends $PaymentID){ $SQLQuery="INSERT INTO orders(walletid,paymentid,dateplaced) VALUES($WalletID,$PaymentID,CURDATE())"; $ParentDone=@mysql_db_query("$DBName",$SQLQuery); // ------------------------ deliberate assignment to test how ROLLBACK works $ParentDone=false; if($ParentDone){ $OrderID=@mysql_insert_id(); $PurchaseDetails="<table width='100%' cellspacing=0 cellpadding=2 style='font-family:verdana;font-size:11px'> <tr><td colspan=6></td></tr><tr><td colspan=6> </td></tr> <tr><td colspan=5><img src=/images/shop/horzbot.gif height=1 width='100%'></td></tr> <tr align=center><td>Product</td><td>Price (<strike>N</strike>)</td><td>Qty.</td><td>Details</td><td>Total (<strike>N</strik e>)</td></tr> <tr><td colspan=5><img src=/images/shop/horzbot.gif height=1 width='100%'></td></tr>"; $Total=0; $count=0; $i=0; foreach($CartContents as $CartItem){ $i++; $ProductID=$CartItem["pid"]; $Product=$Products[$ProductID]["name"]; $Description=$Products[$ProductID]["description"]; $price=$Products[$ProductID]["price"]; $qty=$CartItem["qty"]; $details=$CartItem["details"]; $SubTotal=$qty*$price; $Total += $SubTotal; $details=str_replace("\n","<br>",$details); $SQLQuery=" INSERT INTO orderdetails(orderid,productid,price,quantity,note) VALUES($OrderID,$ProductID,$price,$qty,'$details')"; $ChildDone=@mysql_db_query("$DBName",$SQLQuery); if($ChildDone) $count++; //else{ // @mysql_db_query("$DBName","ROLLBACK"); // break; //} if($Description) $DescriptionLine="<div><font class=description>$Description</font></div>"; else $DescriptionLine=''; $PurchaseDetails.="<tr><td valign=top><font class=product>".$Product."</font>".$DescriptionLine."</td><td align=right valign=top>".number_format($price,2)."</td><td align=center valign=top> ".$CartItem["qty"]."</td><td valign=top>$details</td><td align=right valign=top>".number_format($SubTotal,2)."</td></tr>"; $PurchaseDetails.="<tr><td colspan=5><img src=/images/shop/horzbot.gif height=1 width='100%'></td></tr>"; } $PurchaseDetails.="<tr><td colspan=4 align=right>Total <strike>N</strike></td><td align=right class=total><b>".number_format($Total,2)."</b></td></tr> <tr><td colspan=5><img src=/images/shop/horzbot.gif height=1 width='100%'></td></tr></table>"; //$count=0; //if($count==$i){ @mysql_db_query("$DBName","COMMIT"); $HTML="<table width='100%' cellpadding=2 cellspacing=2 align=center style='font-family:verdana;font-size:12px'> <tr><td><h3>Thank You for your order.</h3></td></tr><!--<tr><td><b>Purchase</b></td></tr>--> <tr><td>Print this page out as your receipt.</td></tr><tr><td>$PurchaseDetails</td></tr> <tr><td><font size=1 face=verdana>Check your <a href=/wallet/wallet.php target=_blank>Wallet</a> for more info.</font></td></tr></table>"; //} //else{ // @mysql_db_query("$DBName","ROLLBACK"); // $HTML='Your order could not be placed. count = '.$count.' : i = '.$i; //} } else{ @mysql_db_query("$DBName","ROLLBACK"); $HTML='Your order could not be placed.'; } } else{ @mysql_db_query("$DBName","ROLLBACK"); $HTML='Your Wallet does not have enough funds for this order.'; } @mysql_close(); } else $HTML='Your cart is empty!'; return $HTML; } ?> --------------------------------------------------------------------- Before posting, please check: http://www.mysql.com/manual.php (the manual) http://lists.mysql.com/ (the list archive) To request this thread, e-mail <[EMAIL PROTECTED]> To unsubscribe, e-mail <[EMAIL PROTECTED]> Trouble unsubscribing? Try: http://lists.mysql.com/php/unsubscribe.php