- 案例——银行转账
1、先建表account
create table account(
id int primary key auto_increment,
balance float
);
insert into account (balance) values (35);
insert into account (balance) values (100);
insert into account (balance) values (200);
2、假设从账户1向账户2转钱
$sql1="update account set balance=balance-10 where id=1";
$sql2="update account set balance=balance+10 where id=2";
如果sql语句1执行成功,2失败,则钱就会凭空消失,这是不允许的。
所以,我们需要有一种方法来控制两个sql语句同时成功,或同时失败——事务!
3、事务
事务用于保证数据的一致性,它由一组相关的dml语句组成,该组的dml语句要么
全部成功,要么全部失败。如网上转账就是典型的要用事务控制的事件。使用时:
若该组dml语句都成功,则提交事务;
若没有全部成功,则回滚,就是把执行过的sql语句再复原。
4、事务回滚的使用
1 <?php 2 //事务 3 $mysqli=new MySQLi("localhost","root","root","test"); 4 if($mysqli->connect_error){ 5 die("连接数据库失败".$mysqli->connect_error); 6 } 7 //将自动提交设为false 8 $mysqli->autocommit(false); 9 $sql1="update account set balance=balance-10 where id=1"; 10 $sql2="update account set balance=balance+10 where id=2"; 11 $res1=$mysqli->query($sql1); 12 $res2=$mysqli->query($sql2); 13 if(!$res1||!$res2){ 14 echo "失败,回滚"; 15 //回滚 16 $mysqli->rollback(); 17 }else{ 18 //成功,则提交事务 19 $mysqli->commit(); 20 } 21 $mysqli->close(); 22 ?>
结果如下:
- mysql控制台中事务的操作
目标:从账户3向账户1转25块
1、开启一个事务 start transaction;
2、做保存点a savepoint a;
账户3减25块 update account set balance=balance-25 where id=3;
3、做保存点b savepoint b;
4、假设这里出错:账户1加20块(少了5块) update account set balance=balance+20 where id=1;
5、这时我们就得回滚到保存点 a rollback to a;
注意:当回滚到保存点a 后,保存点b 就自动被冲掉了
6、如果步骤4没有出错,账户1增加25块,即账户3成功向账户1转账25块,则提交事务 commit;
注意:事务一旦提交,就不能再回滚!!!