持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第九天,点击查看活动详情 最近学习MySQL学到了事务回滚,对其定义及利用有了一定的学习。
应用场景
事物回滚应用的场景还是比较多的,举个简单的例子: 我们银行ATM机进行取钱
- 输入密码,登录自己的账户
- 连接到后台数据库
- 获取账户余额
- 输入转账金额
- 后台数据库对金额进行减去操作
- ATM吐出钱
这些步骤缺一不可,假如说在第五步中后台已经减去了金额但是ATM确没有吐出钱,那么这个取钱行为就不成立 这个时候就需要数据库的 事务回滚 ,即在整个过程中任意步骤出错整个事务就回滚回去
具体代码实现
下面代码简单模仿转账场景:
<?php
//sql基本操作
/*
* create table `pay`(
* id int(10) not null,
* name varchar(20) not null.
* money float(5) not null
* );
* insert pay (id,`name`,`money`) values(01,"alice","100");
insert pay (id,`name`,`money`) values(02,"bob","150");
insert pay (id,`name`,`money`) values(03,"coco","50");
*/
//连接数据库
$link = new Mysqli("localhost","root","zhuangyan","test");
if ($link->connect_error) {
exit($link->connect_error());
}else{
print "连接成功";
}
if(isset($_POST["submit"])){
//关闭自动提交
$link->autocommit(FALSE);
try{
$money = null;
//查询用户余额
$sqls = "select money from `pay` where name = '{$_POST["name"]}'";
$res = $link->query($sqls);
$money = $res->fetch_assoc()["money"];
//更新余额
$sqlt = "update `pay` set `money` =" . ($money-$_POST["money"]) ." where name = '{$_POST["name"]}'";
print ("您的余额为:".$money-$_POST["money"]);
$link->query($sqlt);
if($_POST["money"] > $money) {
throw new Exception ("取钱失败");
}else{
print "取钱成功";
}
//开启提交事务
$link->commit();
}catch(Exception $e){
print $e->getMessage();
$link->rollback();
}
//开启自动提交数据库更改
$link->autocommit(true);
}
$link->close();
?>
<!DOCTYPE html>
<html>
<head>
<title>Pay</title>
</head>
<body>
<form method="POST">
<input type="text" name="name">
<input type="number" name="money">
<input type="submit" name="submit" value="取钱">
</form>
</body>
</html>
在MySQL里面只有innodb支持事务回滚,这边可以自行搜索下MySQL的数据库引擎 因此需要在phpstudy中设置数据库引擎为innodb,之后重启mysql
如果上面这个方法不成功的话可以在建表的时候指定为innodb,如:
create table `pay`(
id int(10) not null,
name varchar(20) not null,
money float(5) not null
)type=innodb;
我这里是建表后意识到这个问题的,所以使用alter进行更新
alter table pay engine=InnoDB;