事务操作

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


使用方法

在 MySQL 中只有使用了 Innodb 数据库引擎的数据库或表才支持事务。

  1. 开启事务:$db->beginTransaction();
  2. 根据结果决定回滚或者提交:$db->rollback(); 或者 $db->commit();

演示数据表 user

				
--
-- 表的结构 `ue_user`
--

CREATE TABLE `ue_user` (
  `id` int(11) NOT NULL,
  `phone` bigint(11) NOT NULL COMMENT '手机号',
  `name` varchar(20) NOT NULL COMMENT '姓名',
  `age` int(3) NOT NULL COMMENT '年龄',
  `money` float(10,2) NOT NULL DEFAULT '0.00' COMMENT '金额',
  `groupid` int(11) NOT NULL COMMENT '用户组',
  `addtime` int(10) NOT NULL COMMENT '添加事件'
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

--
-- 转存表中的数据 `ue_user`
--

INSERT INTO `ue_user` (`id`, `phone`, `name`, `age`, `money`, `groupid`, `addtime`) VALUES
(1, 18800008888, '王二狗', 24, 0.00, 1, 1671519458),
(2, 16600006666, '王富贵', 22, 100.00, 1, 1671605857);

--
-- 转储表的索引
--

--
-- 表的索引 `ue_user`
--
ALTER TABLE `ue_user`
  ADD PRIMARY KEY (`id`);

--
-- 在导出的表使用AUTO_INCREMENT
--

--
-- 使用表AUTO_INCREMENT `ue_user`
--
ALTER TABLE `ue_user`
  MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=3;
COMMIT;
				
			

事务演示

将演示用户A给用户B转账环境

				
<?php

class indexController extends Mb{
    public $dbName = 'user';
    public function index(){
        $this->db->beginTransaction();//开启事务
        $this->db->where('id = ?', [2])->field('money', -50);//扣除王富贵 50 元
        $res = $this->db->where('id = ?', [1])->field('money', 50);//王二狗增加 50 元
        $rowCount = $this->db->rowCount();//获取本次操作影响数据条数
        if($res && $rowCount >=2){//因为操作了两个人的数据,所以必须大于等于2,确保一定成功
            $db->commit();//进行提交
            echo '转账成功';
        }else{
            $db->rollback();//回滚
            echo '转账失败';
        }
    }
}
				
			

事务回滚就是不改变任何数据。当然,真正转账环境中,我们应当优先校验各自的余额,判断转账的余额是否大于被转账的余额,避免余额变成负数,造成损失