thinkphp笔记-数据库的事务和获取器
事务处理
数据库的表引擎需要是InnoDB 才可以使用。事务处理是当我们执行多个SQL查询的时候,彼此之间都在修改数据,数据关联是恒定的,如果成功一条查询,改变了数据,而后一条失败,则前面的数据回滚;比如A给B 3 快钱,A自己-3,B对方+3,但是前一条A给钱执行成功了,但是后一条B收钱失败了,那么这3块钱就是被银行吞掉了,这时就需要在后一条B收款失败后,对前一条A的付款进行回滚、退回或者原路返回的操作,这就叫事务处理;
TP6提供了两种处理方式:自动和手动。比如有如下数据:
id | username | price | |
---|---|---|---|
19 | A | aa@163.com | 60 |
20 | B | bb@163.com | 70 |
先看一下正常情况:A付款-3,B接收+3
// 数据恒定 互相交易 总和始终是60 + 70 = 130
Db::name('user')
->where('id', 19)
->save([
'price' => Db::raw('price - 3')
]);
Db::name('user')
->where('id', 20)
->save([
'price' => Db::raw('price + 3')
]);
假设这时候B+3的交易出错了
Db::name('user')
->where('id', 19)
->save([
'price' => Db::raw('price - 3')
]);
Db::name('user1')
->where('id', 20)
->save([
'price' => Db::raw('price + 3')
]);
因为user1表不存在,所以这时候系统会报错:Base table or view not found: 1146 Table 'grade.tp_user1' doesn't exist
但是我们查看数据库发现,此时的数据已经变了,A-3操作成功了,A的price = 60-3=57,B的因为没成功,price没变化,总和就少了3
自动模式:用Db::transaction(function() { 将执行语句包起来 })
Db::transaction(function() {
Db::name('user')
->where('id', 19)
->save([
'price' => Db::raw('price - 3')
]);
Db::name('user1')
->where('id', 20)
->save([
'price' => Db::raw('price + 3')
]);
});
这时候发现,错误依然存在报错,但是数据库中的数据没有变化,A的price=60,B的price=70
手动模式:与原生过程相似,但是可以自己定制一些现实内容。
//启动事务
Db::startTrans();
try {
/* 执行的语句 */
Db::name('user')
->where('id', 19)
->save([
'price' => Db::raw('price - 3')
]);
Db::name('user1')
->where('id', 20)
->save([
'price' => Db::raw('price + 3')
]);
/* 执行的语句 end */
//提交事务
Db::commit(); // 成功则提交
} catch(\Exception $e) {
echo '执行sql失败,开始回滚数据';
//回滚
Db::rollback(); // 失败的话 就回滚数据
}
获取器
获取器的意思就是:将数据的字段进行转换处理再进行操作;
比如在获取数据列表的时候,将获取到的邮箱字段全部大写。(使用获取器就是不用额外对结果进行php处理了)
// 比如要让输出的email全部改为大写
$user = Db::name('user')->withAttr('email', function($value, $data) {
// $data事整行的数据 $value仅仅事email字段的数据
return strtoupper($value);
})->select();
return json($user);
其中匿名函数有两个参数,$data事整行的数据 ,$value仅仅事email字段的数据。