php mysql %_PHP MySQL事务处理

事务是确保数据库一致的一种机制,是多条 SQL 语句组成的一系列的数据库操作,如果所有的 SQL 语句都操作成功,则认为事务成功,事务会被提交,其修改的数据就会生效。如果在事务中的 SQL 语句有一条或者多条操作失败,则事务不会成功,数据库中的数据将会被回滚到事务开始之前的状态,该事务中所有操作都会被取消。

事务功能是企业级数据库的一个重要部分,因为很多业务过程都包括多个步骤,并不是简单的操作一个数据表就能完成的。比如要在人员管理系统中删除一个人员,既要删除人员的基本资料,还要删除所有与该员工有关的信息,如邮件、文章等等,这一系列的数据库操作就构成了一个事务。

注意:在 MySQL 数据库中,只有使用了 Innodb 数据库引擎的数据库或表才支持事务,更多详细的介绍可以查看《MySQL事务》。

PHP 中想要使用事务有两种方式,一是使用 mysqli_begin_transaction()、mysqli_commit()、mysqli_rollback() 等函数来启动、提交或回滚一个事务;再者就是使用 mysqli_autocommit() 函数来关闭 MySQL 事务的自动提交模式。下面我们先来介绍以下这几个函数。

1) begin_transaction()

mysqli_begin_transaction() 函数可以启动一个事务,其语法格式如下:

面向对象风格的写法:

mysqli::begin_transaction([int $flags = 0[, string $name]])

面向过程风格的写法:

mysqli_begin_transaction(mysqli $link[, int $flags = 0[, string $name]])

参数说明如下:

$link:面向过程风格的写法中,表示由 mysql_connect() 函数创建的数据库连接;

$flags:可选参数,可以是以下所示的值:

MYSQLI_TRANS_START_READ_ONLY:以只读模式启动事务,需要 MySQL5.6 及以上的版本;

MYSQLI_TRANS_START_READ_WRITE:以读写模式启动事务,需要 MySQL5.6 及以上的版本;

MYSQLI_TRANS_START_WITH_CONSISTENT_SNAPSHOT:使用一致快照模式启动事务。

$name:可选参数,用来设置事务的保存点名称。

2) mysqli_commit()

mysqli_commit() 函数可以提交一个事务,其语法格式如下:

面向对象风格的写法:

mysqli::commit()

面向过程风格的写法:

mysqli_commit(mysqli $link)

其中 $link 为使用 mysqli_connect() 函数创建的数据库连接。

3) mysqli_rollback()

mysqli_rollback() 函数可以回退当前事务,其语法格式如下:

面向对象风格的写法:

mysqli::rollback()

面向过程风格的写法:

mysqli_rollback(mysqli $link)

其中 $link 为使用 mysqli_connect() 函数创建的数据库连接。

4) mysqli_autocommit()

mysqli_autocommit() 函数可以打开或关闭本次数据库连接的自动提交事务模式,其语法格式如下:

面向对象风格的写法:

mysqli::autocommit(bool $mode)

面向过程风格的写法:

mysqli_autocommit(mysqli $link, bool $mode)

其中 $link 为使用 mysqli_connect() 函数创建的数据库连接,$mode 用来设置是否打开自动提交模式。

了解了这几个函数的语法后,下面通过示例程序来演示事务的使用。

【示例】假设有 userA 和 userB 两个账户,然后使用 userA 账户向 userB 账号中转账,使用事务来保证 userA 账户中减去一定金额的同时,userB 账户中得到相等的金额。首先需要在数据库中创建一个 InnoDB 类型的数据表 accoubnt,并创建上面的两个账户的信息,如下所示:

DROP TABLE IF EXISTS `account`;

CREATE TABLE `account` (

`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '用户ID',

`name` varchar(45) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL COMMENT '用户名',

`cash` decimal(9, 2) NOT NULL COMMENT '账户余额',

PRIMARY KEY (`id`) USING BTREE

) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8 COLLATE = utf8_unicode_ci ROW_FORMAT = Dynamic;

INSERT INTO `account` VALUES (1, 'userA', 100000.00);

INSERT INTO `account` VALUES (2, 'userB', 90000.00);

使用 mysqli_begin_transaction()、mysqli_commit()、mysqli_rollback() 等函数的实现代码如下所示:

$link = new mysqli('127.0.0.1', 'root', 'root', 'testdb'); // 连接数据库

if(mysqli_connect_errno()){ // 检查连接错误

printf("连接失败:%s
", mysqli_connect_error());

exit();

}

$link -> begin_transaction(); // 开始事务

$success = true; // 设置事务状态

$price = 999; // 转账金额

$sql1 = "UPDATE account SET cash=cash-$price WHERE name='userA'"; // 从 userA 账户转出的 SQL 语句

$result = $link -> query($sql1); // 执行SQL语句

if(!$result || $link->affected_rows != 1){ // 如果执行失败则修改事务状态

$success = false;

}

$sql2 = "UPDATE account SET cash=cash+$price WHERE name='userB'"; // 向 userB 账户中转入的 SQL 语句

$res = $link -> query($sql2); // 执行SQL语句

if(!$res || $link->affected_rows != 1){ // 如果执行失败则修改事务状态

$success = false;

}

if($success){ // 根据事务状态选择提交或者回滚事务

$link->commit();

echo '转账成功!';

}else{

$link->rollback();

echo '转账失败!';

}

$link->close();

?>

使用 mysqli_autocommit() 函数实现的话与上面的代码基本相同,只需要将上面代码的第七行更改为下面的样子即可:

$link -> autocommit(0);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值