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>&nbsp;</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

Reply via email to