欢迎 longtian001 加入本站!
 免费注册  用户登陆  汇款方式  汇款确认  产品报价  联系我们  帮助中心
加入收藏
设为首页
会员体系
申请VIP
网站首页 光盘超市 软件下载 技术文章 专题 用户中心 VIP会员 技术论坛 网站留言 娱乐中心 卓越资源
今天是:2009年01月08日 星期四  您现在位于: 首页 → 技术文章 → 一组新的PHP插件实现My...
   一组新的PHP插件实现MySQL的基础事务
作者:Melonfire  出处:database.ccidnet.com  更新时间: 2007年05月21日 

事务处理支持很长时间以来一直是大多数MySQL开发者的心愿,随着MySQL 4.0的发布,这个心愿最后终于得以实现。MySQL 4.0后不久,拥有一个新的MySQL插件的PHP 5.x也发布了。这个新插件,MySQL Improved,使得PHP开发者通过利用本地的PHP函数,获得了这些新的事务处理能力。这篇简短的教程将向你说明怎样利用这些新的MySQLi函数,用PHP实现以MySQL为基础的事务。

概要

如果你还不知道,那么我可以告诉你,事务只是一组SQL语句,通常因为它们是彼此相互依赖的,所以要在全有或全无(all-or-nothing)的模式下执行。只有当所有组成的语句都执行成功了,一个事务才算是成功了;任何一个语句中的失败应该都会导致系统“回滚”到它先前的状态,以避免数据连接/崩溃问题。

对于这一点,两个银行帐户间的转帐是一个很好的例子。在数据库级,这样的转帐包括两个步骤:首先,从源帐户中扣除转帐的金额,然后将其加到目标帐户中。如果在第二步中发生了错误,那么第一步就必须被取消,以避免不相符的情况(和愤怒的客户聚众滋事)。事务安全系统将自动地撤到系统先前的“快照”。

大多数数据库(包括MySQL)通过一个命令的组合来完成这个:

START TRANSACTION命令标志着一个新的事务组的开始。它后面常接一系列的SQL命令。

COMMIT命令标志着一个事务组的结束,表示事务期间做的所有改变应该被提交或者使之永久化。

ROLLBACK命令标志着一个事务组的结束,表示事务期间所做的所有改变应该被撤消。

PHP中的事务处理函数。

PHP中的MySQLi插件引进了新的函数,帮助开发者利用MySQL的事务处理能力。实质上,这些函数对等地被叫做SQL START TRANSACTION,COMMIT和 ROLLBACK命令。列表A为你展示了一个例子:

列表A:

<?php
// 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 |

+----+------------+---------+

|  1 | Savings #1 |    1000 |

|  2 | Current #1 |    2000 |

|  3 | Current #2 |    3000 |

+----+------------+---------+

3 rows in set (0.34 sec)

现在,需要建立一个简单的界面,使用户能够输入一个现金数额,实现从一个帐户到另一个的转帐。实际的“交易”将用两个UPDATE语句来执行,一个将转帐金额从源帐户取出,即借方,另一个将转帐金额记入目标帐户,即贷方。假设我们所做的是在帐户之间进行转帐,那么所有帐户的可用结余总额(00)应该一直保持不变。

列表B显示了可能的代码:

列表 B:

<?php
// connect to database
$dbh = mysqli_connect("localhost", 
"user", "pass", "test") or die("Cannot connect");

// turn off auto-commit
mysqli_autocommit($dbh, FALSE);

// look for a 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);
?>
<html>
<head></head>
<body>

<h3>TRANSFER</h3>
<form action="<?php echo $_SERVER['PHP_SELF'];
 ?>" method="post">
Transfer $ <input type="text" name="amt" size="5"> from

<select name="from">
<?php
foreach ($accounts as $a) {
    echo "<option value="" . $a['id'] . "
">" . $a['label'] . "</option>";    
}
?>
</select>

to

<select name="to">
<?php
foreach ($accounts as $a) {
    echo "<option value="" . $a['id'] 
. "">" . $a['label'] . "</option>";    
}
?>
</select>

<input type="submit" name="submit" value="Transfer">

</form>

<h3>ACCOUNT BALANCES</h3>
<table border=1>
<?php
foreach ($accounts as $a) {
    echo "<tr><td>" . $a['label'] . 
"</td><td>" . $a['balance'] . "</td></tr>";    
}
?>
</table>
</body>
</html>

像你所看到的那样,脚本以连接数据库和关闭自动提交开始。然后执行一个SELECT查询,检索所有帐户的现金收支,接着构造一个有下拉式界面的表格,选择交易要用到的来源/目标帐户。

最初的表格

一旦表格完成并提交后,两个UPDATE查询就开始实际执行借和贷操作。注意每一个查询的尾端都带有一个mysqli_rollback(),如果查询失败的话,它将被激活。假设没有查询失败的话,新的收支表就通过调用mysqli_commit()储存到数据库中。那时数据库连接就被关闭。

你可以自己试一下,从Savings #1转0到Current #2。一旦你执行转帐之后,你将看到如图表B所示的平衡表的新结果。

交易完成之后的状况

提示:当然,这只是一个简单的双命令的事务。通常,当有许多SQL语句要一起执行的时候,你可以用这种事务模型,一个语句的失败对其他语句有串联的影响。在这些情况下,你会发现将mysqli_query()和mysqli_rollback()的调用压缩到一个单独的用户自定义的函数中,需要的时候调用它会更加简便。

正如你所看到的那样,用PHP和MySQL执行一个事务处理模型可以使你的MySQL数据库对查询执行的错误更稳固。但是,在你开始动手重写代码和使用这个模型之前,值得注意的是,事务确实会增加系统性能管理的消耗,所以,在实现这个模型之前,做一个成本效益分析始终是个好主意。

 (本文已被浏览 2261 次)
 发布人:sdccf
 → 推荐给我的好友
上篇文章:MySQL 5 C API 访问数据库例子程序
下篇文章:简要安装 FreeBSD 6.2 及配置桌面环境
 相关文章:
没有相关文章

相关搜索
查看百度中关于一组新的PHP插件实现MySQL的基础事务的更多内容
查看google中关于一组新的PHP插件实现MySQL的基础事务的更多内容
   文章分类
操作系统 |
SCO_UNIX  Sun_Solaris  IBM_AIX  HP_UX  Linux  BSD  Tru64_UNIX 
通用UNIX知识  Windows  Minix 
程序设计 |
Shell编程  C/C++  汇编  PHP  JAVA  Perl  Python 
ASP/HTML  XML  中间件 
数据库 |
Oracle  Informix  Sybase  Fox  DB2  SQL  MySQL 
PostgreSQL 
网络应用 |
网络应用 
计算机硬件 |
计算机主机  打印机  路由器  交换机  终端  磁带机  MO 
刻录机  终端服务器  调制解调器 
   文章评论
  → 评论内容 (点击查看)   共0条评论,每页显示5条评论   浏览所有评论
(没有相关评论)
  → 发表我的评论
您的姓名: 您的Email:
评论内容:
250字内
发表评论:      发表评论须知 →
  • 尊重网上道德,遵守《全国人大常委会关于维护互联网安全的决定》及中华人民共和国其他各项有关法律法;
  • 本站有权保留或删除您发表的任何评论内容;
  • 关于我们 ┋  网站留言 ┋  网站地图 ┋  友情链接 ┋  与我在线 ┋  汇款确认 ┋  管理 ┋  TOP
    Unix爱好者家园  http://www.unix-cd.com/
    联系我们:sdccf@163.com
    腾讯QQ: 7644599
    备案序号:鲁ICP备05000455号
    Copyright (c) 2001-2008 Unix-cd.com. All Rights Reserved.