PHP的事务处理机制

应用事务处理技术实现转账的代码如下:  
    $tob=$_POST['tob'//注:请补充'tob'后边一个“]”,腾讯的编辑器总是把它过滤了。
    $conn=new mysqli("localhost","root","root","db_database09"); 
    $conn->query("set names gb2312"); 
    $conn->autocommit(false); 
    if(!$conn->query("update tb_zy set money=money-'".$tob."' where flag='mrsoft'")){ 
     $conn->rollback(); 
    
    if(!$conn->query("update tb_zy set money=money+'".$tob."' where flag='mr'")){ 
     $conn->rollback(); 
    
    $conn->commit(); 
    $conn->autocommit(true); 
    echo "
  首先调用mysqli类的autocommit()方法关闭数据库的自动提交(MySQL数据库默认为自动提交),然后减少A账户一定数量的金额,并判断查询是否顺利执行,如果在此过程中发生意外,则通过调用mysqli类的rollback()方法回滚,不做任何处理,反之为B账户增加相同的金额。最后通过调用mysqli类的commit()方法提交查询,实现转账。
 
 \<\?php
$handler mysql_connect("localhost", "root", "");
mysql_select_db("task");
mysql_query("SET AUTOCOMMIT=0"); //设置为不自动提交,因为MYSQL默认立即执行
mysql_query("BEGIN"); //开始事务定义
if (!mysql_query("insert into trans (id) values('2')")) {
 mysql_query("ROOLBACK"); //判断当执行失败时回滚
}
if (!mysql_query("insert into trans (id) values('4')")) {
 mysql_query("ROOLBACK"); //判断执行失败回滚
}
mysql_query("COMMIT"); //执行事务
mysql_close($handler);
\?\>
 
<完>
其它相关内容:
 MYSQL的事务处理主要有两种方法。
   1、用begin,rollback,commit来实现
        begin 开始一个事务
        rollback 事务回滚
        commit  事务确认
    2、直接用set来改变mysql的自动提交模式
       MYSQL默认是自动提交的,也就是你提交一个QUERY,它就直接执行!我们可以通过
      set autocommit=0   禁止自动提交
      set autocommit=1 开启自动提交
   来实现事务的处理。
但注意当你用 set autocommit=0 的时候,你以后所有的SQL都将做为事务处理,直到你用commit确认或rollback结束,注意当你结束这个事务的同时也开启了个新的事务!按第一种方法只将当前的作为一个事务!
个人推荐使用第一种方法!
   MYSQL中只有INNODB和BDB类型的数据表才能支持事务处理!其他的类型是不支持的!(切记!)
 
PHP中的事务处理函数
PHP中的MySQLi插件引进了新的函数,帮助开发者利用MySQL的事务处理能力。实质上,这些函数对等地被叫做SQL START TRANSACTION,COMMIT和 ROLLBACK命令。列表A为你展示了一个例子,列表A:
 
// connect to database
$dbh mysqli_connect($host, $user, $pass, $db);
 
// turn off auto-commit
mysqli_autocommit($dbh, FALSE);
 
// run query 1
$result mysqli_query($dbh, $query1);
 
if ($result !== TRUE) {
mysqli_rollback($dbh); // if error, roll back transaction
}
 
// run query 2
$result mysqli_query($dbh, $query2);
 
if ($result !== TRUE) {
mysqli_rollback($dbh); // if error, roll back transaction
}
// and so on...
 
// assuming no errors, commit transaction
mysqli_commit($dbh);
 
// close connection
mysqli_close($dbh);

在PHP 中执行一项事务有三个基本的步骤:
第一步是始终关掉数据库的“auto-commit”,它实质上意味着系统在你作出改变时就保存它们。这一点是很重要的,因为在一个事务处理环境中,你应该只有在确定了所有事务处理的“unit”都成功完成了以后,才保存你所做的改变。你可以通过mysqli_autocommit()函数关掉数据库的自动提交。
接下来,通过mysqli_query()函数,继续用通常的方法进行INSERT、UPDATE和/或DELETE查询。检验每一个查询返回的值,弄清楚它是否成功了是很重要的。如果其中任何一个查询失败了,mysqli_rollback()函数就会被用来将系统返回到事务进行之前的状态。
假设组成事务组的所有命令都成功执行了,就要用mysqli_commit()函数将变化保存到数据库系统。请注意,一旦这个函数被调用,事务就不能被撤消了。
工作实例
要了解这个在实践中是怎么工作的,让我们回到前面讨论过的银行转帐的例子.我们假设你的任务是建立一个简单的Web应用程序,让用户在他们的银行帐户间转帐。我们再进一步假设一个单独用户的帐户存储在一个MySQL数据库中,如下所示:
mysql> SELECT FROM accounts;
+----+------------+---------+
id label balance |
+----+------------+---------+
Savings #1 1000 |
Current #1 2000 |
Current #2 3000 |
+----+------------+---------+
rows in set (0.34 sec)
现在,需要建立一个简单的界面,使用户能够输入一个现金数额,实现从一个帐户到另一个的转帐。实际的“交易”将用两个UPDATE语句来执行,一个将转帐金额从源帐户取出,即借方,另一个将转帐金额记入目标帐户,即贷方。假设我们所做的是在帐户之间进行转帐,那么所有帐户的可用结余总额($6000)应该一直保持不变。
列表B显示了可能的代码,列表 B:
// connect to database
$dbh mysqli_connect("localhost", "user", "pass", "test") or die("Cannot connect");
 
// turn off auto-commit
mysqli_autocommit($dbh, FALSE);
 
// look for transfer
if ($_POST['submit'] && is_numeric($_POST['amt'])) {
// add $$ to target account
$result mysqli_query($dbh, "UPDATE accounts SET
balance balance $_POST['amt'] WHERE id $_POST['to']);
if ($result !== TRUE) {
mysqli_rollback($dbh); // if error, roll back transaction
}
// subtract $$ from source account
$result mysqli_query($dbh, "UPDATE accounts
SET balance balance $_POST['amt'] .
WHERE id $_POST['from']);
if ($result !== TRUE) {
mysqli_rollback($dbh); // if error, roll back transaction
}
// assuming no errors, commit transaction
mysqli_commit($dbh);
}
// get account balances
// save in array, use to generate form
$result mysqli_query($dbh, "SELECT FROM accounts");
while ($row mysqli_fetch_assoc($result)) {
$accounts[] $row;
}
// close connection
mysqli_close($dbh);
?像你所看到的那样,脚本以连接数据库和关闭自动提交开始。然后执行一个SELECT查询,检索所有帐户的现金收支,接着构造一个有下拉式界面的表格,选择交易要用到的来源/目标帐户。图表A显示了最初的表格。
最初的表格
一旦表格完成并提交后,两个UPDATE查询就开始实际执行借和贷操作。注意每一个查询的尾端都带有一个mysqli_rollback(),如果查询失败的话,它将被激活。假设没有查询失败的话,新的收支表就通过调用mysqli_commit()储存到数据库中。那时数据库连接就被关闭。
你可以自己试一下,从Savings #1转$500到Current #2。一旦你执行转帐之后,你将看到如图表B所示的平衡表的新结果。
交易完成之后的状况。
提示:当然,这只是一个简单的双命令的事务。通常,当有许多SQL语句要一起执行的时候,你可以用这种事务模型,一个语句的失败对其他语句有串联的影响。在这些情况下,你会发现将mysqli_query()和mysqli_rollback()的调用压缩到一个单独的用户自定义的函数中,需要的时候调用它会更加简便。
正如你所看到的那样,用PHP和MySQL执行一个事务处理模型可以使你的MySQL数据库对查询执行的错误更稳固。但是,在你开始动手重写代码和使用这个模型之前,值得注意的是,事务确实会增加系统性能管理的消耗,所以,在实现这个模型之前,做一个成本效益分析始终是个好主意

 

这里记录一下php操作mysql事务的一些知识

要知道,MySQL默认的行为是在每条SQL语句执行后执行一个COMMIT语句,从而有效的将每条语句独立为一个事务。但是,在使用事务时,是需要执行多条sql语句的,那么针对执行多条SQL语句来完成一个事务有两种办法:

1、关闭自动提交

如果SET AUTOCOMMIT=0;也就是关闭了自动提交,那么任何commit或rollback语句都可以触发事务提交;如果SET AUTOCOMMIT=1;也就是开启了自动提交(默认值),那么必须要以begin或者START TRANSACTION声明事务的开始,然后再以commit或rollback语句都可以触发事务提交。

例子:

 

[php]  view plain copy
  1. $db->query('SET autocommit=0');  
  2. $db->query('update member set money=money+'.$money.where memberId='.$memberId);  
  3. $db->query('insert into mem_log(money) values('.$money.')');  
  4. $db->query('commit');  
  5. $db->query('insert into test(str) values('.sql_encode($msg).')');//该条数据无法插入。因为autocommit=0  

因此使用该方法时,注意,在事务结束。要恢复autocommit的值。

 

 

[php]  view plain copy
  1. $db->query('SET autocommit=0');  
  2. $db->query('update member set money=money+'.$money.where memberId='.$memberId);  
  3. $db->query('insert into mem_log(money) values('.$money.')');  
  4. $db->query('commit');  
  5. $db->query('SET autocommit=1');  
  6. $db->query('insert into test(str) values('.sql_encode($msg).')');//恢复autocommit=1后,该语句可成功插入  

 

2、显示打开一个事务

 

显示打开一个事务,就比上面的方法要简单些,不需要设置autocommit的值,也不用在事务结束后恢复autocommit的值。即,如果想保留autocommit开关打开,则通过begin或者START TRANSACTION声明事务,声明后,autocommit开关将会被禁用,直到您使用COMMIT或ROLLBACK结束事务为止,事务结束,autocommit开关将被打开。

 

[php]  view plain copy
  1. $db->query('START TRANSACTION');  
  2. $db->query('update member set money=money+'.$money.where memberId='.$memberId);  
  3. $db->query('insert into mem_log(money) values('.$money.')');  
  4. $db->query('commit');  
  5. $db->query('insert into test(str) values('.sql_encode($msg).')');//该条数据可以插入  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值