一个有关 decrement 和 increment 的问题
先说一下问题出现的场景
我是用的数据库是mysql, 表里面有一个虚拟币的字段, 某些情况下需要去减这个字段, 我都是使用 decrement
和 decrement
这两个方法取操作的, 数据库对这个字段设置的是 无符号, 也就是大于0的
XxModel::where(xxx)->decrement('sum', 20); //是这么操作的
一般情况下是正常的, 但是今天的情况是, 我的账户虚拟币 还有20个, 但是我代码减去100
XxModel::where(xxx)->decrement('sum', 100);
问题就出现了, 这个代码返回的值是1
, 数据库字段值变成0
, 这是什么情况?
后来我又尝试了以下的方法, 但是得到的结果都一致
DB::table('xxx')->where(xxx)->decrement('sum', 100);
DB::table('xxx')->where(xxx)->update(['sum' => DB::raw('sum - 100')]);
XxModel::where(xxx)->first()->decrement('sum', 100);
我在数据库执行
update table set sum = sum - 100 where xxx
会出现报错信息
Out of range value for column 'sum' at row 123016, Time: 0.089000s
所以laravel 的 decrement
是怎么算的呢
decrement执行的是update,返回的是执行成功是受影响的行数,而不是最后的结果。
在你你使用:update table set sum = sum - 100 where xxx会出现:BIGINT UNSIGNED value is out of range in的错误信息,这个错误信息和实际的意义是一样的。
但是你执行:update table set sum = -80 where xxx时是可以执行成功的。执行结果就是0,这可能是mysql机制问题。
decrement使用Update
1、提前判断是剩余的数量是否够扣除。
2、可以使用原生sql
3、建议在数据库中,这个值最好不要设置成无符号型字段,应该可以为负数,你可以理解成用户透支,也可以做到出与入的统一。