免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 14247 | 回复: 6
打印 上一主题 下一主题

PHP中mysql事务的完整性 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2006-06-04 22:11 |只看该作者 |倒序浏览
小弟在写一个PHP程序,程序里的数据库操作和转帐的过程类似,把一个表中的金额转到另一个里头,突然想到一个问题:这在PHP里头必然涉及到两次对表的操作,那么事务指的什么?是单独的一次操作还是这两次?如果是指的单独的一次操作那么如何保证数据的一致性?如果指的是这两次操作,那么MYSQL中是如何来保证事务的完整性的?

论坛徽章:
0
2 [报告]
发表于 2006-06-05 00:02 |只看该作者
事务(transaction)是由查询和/或更新语句的序列组成。
用 begin、start transaction 开始一个事务,rollback 回滚事务,commit 提交事务。
在开始一个事务后,可以有若干个 SQL 查询或更新语句,每个 SQL 递交执行后,还应该有判断是否正确执行的语句,以确定下一步是否回滚,若都被正确执行则最后提交事务。
事务一旦回滚,数据库则保持开始事务前状态。就好象一个被编辑的文件不存盘退出,自然还是保持文件原来的样子。
所以,事务可被视为原子操作,事务中的 SQL,要么全部执行,要不一句都不执行。

论坛徽章:
0
3 [报告]
发表于 2006-06-06 12:51 |只看该作者
你说的是ODBC JDBC里的处理方法,可是PHP里头好像没有这样的COMMIT ROLLBACK,那么PHP里头是如何做的?

论坛徽章:
5
2015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:53:172015亚冠之水原三星
日期:2015-06-02 16:34:202015年亚冠纪念徽章
日期:2015-10-19 18:13:37程序设计版块每日发帖之星
日期:2015-11-08 06:20:00
4 [报告]
发表于 2006-06-06 13:14 |只看该作者
首先要使用支持事务的数据库 后端比如 InnoDB
我只知道C_API有相关事物的函数PHP 应该也有吧 看看MySQL和PHP的手册

论坛徽章:
0
5 [报告]
发表于 2006-06-06 13:39 |只看该作者
原帖由 rsuhkoi 于 2006-6-6 12:51 发表
你说的是ODBC JDBC里的处理方法,可是PHP里头好像没有这样的COMMIT ROLLBACK,那么PHP里头是如何做的?

你理解上有问题,事务是数据库的东西,为什么需要在 PHP 这个编程语言中提供支持?
PHP + MySQL 用事务,就是直接在 PHP 中用:mysql_query("begin")、mysql_query("rollback")、mysql_query("commit") 来递交啊。
要注意的是,MySQL 总的数据表必须是 innodb 或者 bdb 等支持事务的表类型。更多的看 MySQL 手册。

[ 本帖最后由 rardge 于 2006-6-6 14:03 编辑 ]

论坛徽章:
0
6 [报告]
发表于 2006-06-06 23:28 |只看该作者
我才学PHP不过2个月,接触到的书上的例子基本上都没有提到这个问题,手册上也没有说明白,你能给个好点的参考书或是手册吗?

论坛徽章:
0
7 [报告]
发表于 2006-06-07 11:44 |只看该作者
请注意:把相关编码设定为 utf8,PHP 文件也存为 utf-8 编码,否则示例中中文乱码。

我表结构,注意表类型用的是 InnoDB。

  1. mysql> show create table test.i_t\G
  2. *************************** 1. row ***************************
  3.        Table: i_t
  4. Create Table: CREATE TABLE `i_t` (
  5.   `id` int(10) unsigned NOT NULL auto_increment,
  6.   `age` int(10) unsigned default NULL,
  7.   PRIMARY KEY  (`id`)
  8. ) ENGINE=InnoDB DEFAULT CHARSET=utf8
  9. 1 row in set (0.00 sec)
复制代码


  1. <?php
  2. function html_header() {
  3.         $content = <<<HTML
  4. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
  5. <html>
  6. <head>
  7. <title>数据库事务处理示例</title>
  8. <meta HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=utf-8">
  9. </head>
  10. <body>
  11. HTML;

  12.         echo $content;
  13. }

  14. function html_footer() {
  15.         $content = <<<HTML
  16. </body>
  17. </html>
  18. HTML;

  19.         echo $content;
  20. }

  21. function print_result(&$result, $caption) {
  22.         echo '<table width="500" border="1">';
  23.         echo '<caption>' . $caption . '</caption>';
  24.         echo '<tr height="22"><td>ID</td><td>AGE</td></tr>';

  25.         $rows = mysql_num_rows($result);
  26.         switch($rows) {
  27.         case 0:
  28.                 echo '<tr><td colspan=\'2\'>无记录</td></tr>';
  29.                 break;
  30.         default :
  31.                 for($i = 0; $i< $rows; $i++) {
  32.                         $row = mysql_fetch_array($result);
  33.                         echo '<tr><td>' . $row['id'] . '</td><td>' . $row['age'] . '</td></tr>';
  34.                 }
  35.                 break;
  36.         }

  37.         echo '</table>';
  38.         echo '<br>';
  39. }
  40. ?>
  41. <?php
  42.         html_header();

  43.         /* 参数定义 */
  44.         define('HOST', 'localhost');
  45.         define('USER', '');
  46.         define('PASSWD', '');
  47.         define('DB', 'test');
  48.         define('TB', 'i_t');

  49.         /* 示例 SQL 语句组 */
  50.         $SQL[] = 'INSERT INTO ' . TB . ' (age) VALUES (23)';
  51.         $SQL[] = 'INSERT INTO ' . TB . ' (age) VALUES (30)';
  52.         $SQL[] = 'INSERT INTO ' . TB . ' (age) VALUES (18)';

  53.         /* 连接 MySQL 服务器 */
  54.         $link_id = @ mysql_connect(HOST, USER, PASSWD) or exit(mysql_error());
  55.         mysql_select_db(DB, $link_id) or exit(mysql_error());

  56.         /*********************
  57.         * 例1
  58.         * 数据回卷的情形
  59.         *********************/

  60.         /* 查询当前数据表记录状态 */
  61.         $result = mysql_query('SELECT id, age FROM ' . TB, $link_id);
  62.         print_result($result, '例1,初始状态');

  63.         /* 创建事务 */
  64.         mysql_query('START TRANSACTION', $link_id) or exit(mysql_error());

  65.         /* 提交 SQL */
  66.         for($i = 0; $i < count($SQL); $i++) {
  67.                 mysql_query($SQL[$i], $link_id); // 假设无错误发生
  68.         }

  69.         /* 查询当前数据表记录状态 */
  70.         $result = mysql_query('SELECT id, age FROM ' . TB, $link_id);
  71.         print_result($result, '此状态仅在该事务中可见');

  72.         /* 回卷 -- 也意味着中止此次事务 */
  73.         mysql_query('ROLLBACK', $link_id) or exit(mysql_error());

  74.         /* 查询当前数据表记录状态 */
  75.         $result = mysql_query('SELECT id, age FROM ' . TB, $link_id);
  76.         print_result($result, '人为回卷事务,数据表最终状态');


  77.         /*********************
  78.         * 例2
  79.         * 数据被正式提交的情形
  80.         *********************/

  81.         /* 查询当前数据表记录状态 */
  82.         $result = mysql_query('SELECT id, age FROM ' . TB, $link_id);
  83.         print_result($result, '例2,初始状态');

  84.         /* 创建事务 */
  85.         mysql_query('START TRANSACTION', $link_id) or exit(mysql_error());

  86.         /* 提交 SQL */
  87.         for($i = 0; $i < count($SQL); $i++) {
  88.                 mysql_query($SQL[$i], $link_id);
  89.         }

  90.         /* 查询当前数据表记录状态 */
  91.         $result = mysql_query('SELECT id, age FROM ' . TB, $link_id);
  92.         print_result($result, '此状态仅在该事务中可见');

  93.         /* 提交事务 */
  94.         mysql_query('COMMIT', $link_id) or exit(mysql_error());

  95.         /* 查询当前数据表记录状态 */
  96.         $result = mysql_query('SELECT id, age FROM ' . TB, $link_id);
  97.         print_result($result, '提交事务,数据表最终状态');


  98.         /*********************
  99.         * 例3
  100.         * 如果 SQL 执行过程中有错误发生的情形(数据应该被回卷)
  101.         *********************/

  102.         /* 查询当前数据表记录状态 */
  103.         $result = mysql_query('SELECT id, age FROM ' . TB, $link_id);
  104.         print_result($result, '例3,初始状态');

  105.         /* 创建事务 */
  106.         mysql_query('START TRANSACTION', $link_id) or exit(mysql_error());

  107.         /*
  108.         * 提交 SQL
  109.         * 人为添加一条错误的 SQL
  110.         */
  111.         $SQL[] = 'INSERT INTO ' . TB . ' (sex) VALUES (100)'; // 数据表中并无 sex 字段
  112.         for($i = 0; $i < count($SQL); $i++) {
  113.                 if(! mysql_query($SQL[$i], $link_id)) {
  114.                         /*
  115.                         * 按理每次更新查询都应该进行判断,前两个例子都没做处理。
  116.                         * 若 SQL 执行出错,回卷本次事务操作。
  117.                         */
  118.                         $err_msg = mysql_error();

  119.                         mysql_query('ROLLBACK', $link_id) or exit(mysql_error());

  120.                         /* 查询当前数据表记录状态 */
  121.                         $result = mysql_query('SELECT id, age FROM ' . TB, $link_id);
  122.                         print_result($result, '错误:' . $err_msg . '。回卷事务,数据表最终状态');

  123.                         html_footer();
  124.                         exit();
  125.                 }
  126.         }

  127.         /*
  128.         * 若上面执行无错误发生,则会运行到此。
  129.         * 提交事务
  130.         */
  131.         mysql_query('COMMIT', $link_id) or exit(mysql_error());

  132.         /* 查询当前数据表记录状态 */
  133.         $result = mysql_query('SELECT id, age FROM ' . TB, $link_id);
  134.         print_result($result, '提交事务,数据表最终状态');
  135.         html_footer();
  136. ?>
复制代码


以上是事务的基础应用,更多关于事务特性的资料,要么看 MySQL 手册(主要在 InnoDB 手册),要么找本数据库系统理论方面的书籍去看。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP