交易错误

时间:2012-08-26 19:42:20

标签: php mysql transactions

我需要帮助让这段事务代码按预期工作。看来我没有正确地放置BEGIN和COMMIT。每当增加/减少金额时,余额应增加/减少,但不是。

<?php
require_once 'login.php';
$db_server = mysql_connect($db_hostname, $db_username, $db_password);
if (!$db_server) die("Unable to connect to MySQL: " . mysql_error());
mysql_select_db($db_database, $db_server)
or die("Unable to select database: " . mysql_error());

if(isset($_POST['amount']))
{
    if(isset($_POST['ADD']) && $number !="")  
    {
          mysql_query("BEGIN"); 
          $query="UPDATE accounts SET balance=balance+amount WHERE number='12345'"; 
    }
    else
    {
          $query="UPDATE accounts SET balance='balance-amount' WHERE number='12345'";
          mysql_query($query);     
    }

  if($query){
     mysql_query("COMMIT");
  }
  else{
    mysql_query("ROLLBACK");
  }

}

echo <<<_END
<form action='transaction.php' method="post"><pre>
Enter the amount: <input type="text" name="amount" />
<input type="submit" value="ADD VALUE" />   <input type="submit" value="SUBTRACT VALUE" />
</pre></form>
_END;

$query="SELECT balance FROM accounts WHERE number='12345'";
$result=mysql_query($query);
$rows=mysql_num_rows($result);

for($j=0; $j<$rows; ++$j)
{ 
   $row=mysql_fetch_row($result);
echo <<<_END
   <pre>
Your current balance is $row[$j]
   </pre>
_END;

}


echo <<<_END
<form action="transaction.php" method="post">
<input type="hidden" name="ADD" value="yes" />
<input type="hidden" name="SUBTRACT" value="yes" />
</pre></form>
_END;

mysql_close($db_server);

 ?>

我做错了什么?

2 个答案:

答案 0 :(得分:2)

你的代码非常丑陋而且不行。例如,您没有在查询中设置amount,如果您发布ADD则不会发生任何事情,如果不是ADD代码'balance-amount'不正确,则应该balance-$amount $number 1}},mysql_*未设置在任何地方,等等......

请尝试使用PDO,因为$db = new PDO('mysql:host='.$db_hostname.';dbname='.$db_database, $db_username, $db_password, array(PDO::ATTR_EMULATE_PREPARES => false)); if(isset($_POST['amount']) && ($_POST['amount'] != '') && ($_POST['number'] != '')){ if($_POST['type'] == 'ADD') { $query = "UPDATE `accounts` SET `balance`=`balance`+:amount WHERE `number`=:number"; } else { $query = "UPDATE `accounts` SET `balance`=`balance`-:amount WHERE `number`=:number"; } try { $db->beginTransaction(); $stmt = $db->prepare($query); $stmt->execute(array(':amount' => $_POST['amount'], ':number' => $_POST['number'])); $db->commit(); } catch(PDOException $ex) { $db->rollBack(); echo $ex->getMessage(); } } 函数已被弃用...

echo <<<_END
<form action='transaction.php' method="post"><pre>
Enter the amount: <input type="text" name="amount" /> <br />
Number: <input type="text" name="number" value="12345" /><br />
Type: <select name="type"><option value="ADD">ADD</option><option value="SUBSTRACT">SUBSTRACT</option></select>
<input type="submit" value="Make changes" />
</pre></form>
_END;

另一个错误是你的表单,你没有发送任何东西,试试这个:

$stmt = $db->query(SELECT `balance` FROM `accounts` WHERE `number`='12345');
$row = $stmt->fetch(PDO::FETCH_ASSOC);
echo "<pre>Your current balance is ".$row['balance']."</pre>";

获取信息:

{{1}}

答案 1 :(得分:1)

查看作业和执行的顺序:

  • 如果设置了ADD,则执行BEGIN,创建查询字符串,但从不执行它。
  • 如果未设置ADD,则不会执行BEGIN,但会创建并执行查询。

两者都有些不对劲。在所有情况下,$query都设置为总是ROLLBACK,但您并不总是启动事务。

你需要更像的东西:

if (isset($_POST['amount']))
{
    mysql_query("BEGIN"); 
    if (isset($_POST['ADD']) && $number !="")  
    {
        $query="UPDATE accounts SET balance=balance+amount WHERE number='12345'"; 
    }
    else
    {
        $query="UPDATE accounts SET balance='balance-amount' WHERE number='12345'";
    }
    mysql_query($query);     

    if (...query succeeded...)
    {
        mysql_query("COMMIT");
    }
    else
    {
        mysql_query("ROLLBACK");
    }
}

我不确定你是如何发现查询有效的;您可能需要捕获并检查mysql_query()返回的值。

在某些时候,您将不得不重新审视在设置ADD时从余额中减去金额但该数字为空字符串的事实。但是你也需要同时修复重复的'12345'。如果没有设置数字,你可能不应该在数据库中做任何事情;你应该完全拒绝这个请求。


PS:我认为mysql_*函数已被弃用。请改用PDO。

请记住要避免SQL Injection - 使用mysql_*功能比使用PDO要困难得多。