php不能抛出mysql异常_php抛出sql异常

这篇博客讨论了乐观锁在MySQL InnoDB存储引擎下的应用,通过版本号(version)字段防止并发更新时的冲突。作者提到了在version字段达到最大值时可能遇到的问题,并提出了引入flag字段来解决version溢出问题,确保并发场景下的数据一致性。文章还包含了具体的SQL更新语句示例,展示了如何在更新时检查和更新version字段。
摘要由CSDN通过智能技术生成

"

比如 MySQL,InnoDB,行级锁;

不会出现同时 Update 成功的情况,乐观锁 update 带上了 version 条件,更新不到记录时受影响记录数为 0,后续做相关的业务处理。######ok,我陷入可一个误区,我知道了,是安全的,如果不在其他业务逻辑进行表操作的情况下。######

把版本号当做条件,第二个update 的时候是更新不到记录的,受影响条数是 0,然后抛出异常,回滚事务。######如果两个线程同时获取到相同的version字段,两个同时update ,当前数据记录中version字段值 == 查询出的暂存version字段条件成立,会不会同时更新为相同的结果,最终version字段只是+1?######

Update的时候innoDB会行级锁吧    乐观锁之后第二个应该是影响0行吧   不会报错的 ######

就算2个或者多个线程同时update,那么数据就出现了不确定性,可能是第一个线程update的数据,也可能是后面线程的数据,你说的+1情况,不明白为什么会出现!######

不会的,你第一个update后version+1了,后一个匹配不到数据######

可信答案:

######

这里抛出一个相关的问题: @乌龟壳 version字段一直在自增,当其自增到最大值时,这个临界点该如何处理? 我的做法是引入一个字段flag,用于标记version应该自增还是自减. 乐观锁常用于并发冲突少,同时又要保证正确读写的场景. 我把乐观锁用到了程序读写用户会话session表上:

$table = $app['db_prefix'].'session';

switch(true) {

//version 类型 smallint 范围 0 到 65535

case ($app['user']['session_flag'] == 1 && $app['user']['session_version'] != 65535):

$sql = "UPDATE `{$table}` SET `session` = ?, `version` = ?

WHERE `user_id` = ? AND `version` = ? AND `flag` = 1";

$version_increase = true;

break;

case ($app['user']['session_flag'] == 1 && $app['user']['session_version'] == 65535):

$sql = "UPDATE `{$table}` SET `session` = ?, `version` = ?, `flag` = -1

WHERE `user_id` = ? AND `version` = ? AND `flag` = 1";

$version_increase = false;

break;

case ($app['user']['session_flag'] == -1 && $app['user']['session_version'] != 0):

$sql = "UPDATE `{$table}` SET `session` = ?, `version` = ?

WHERE `user_id` = ? AND `version` = ? AND `flag` = -1";

$version_increase = false;

break;

case ($app['user']['session_flag'] == -1 && $app['user']['session_version'] == 0):

$sql = "UPDATE `{$table}` SET `session` = ?, `version` = ?, `flag` = 1

WHERE `user_id` = ? AND `version` = ? AND `flag` = -1";

$version_increase = true;

break;

}

$stmt = $db->prepare($sql);

$stmt->execute(array(

$session,

$version_increase ? $app['user']['session_version'] + 1 : $app['user']['session_version'] - 1,

$app['user']['id'],

$app['user']['session_version'],

));

return ($stmt->rowCount() == 0) ? false : true;

######楼主的头像都被吓黑了######回复

@eechen : 你加一个flag,本质就是用true和false两种状态,配合version字段,组合成最终比smallint还要多两倍的可能的值。实际上你自己造了一个数据类型而已。######回复

@eechen : 到了溢出值回0,和你说的倒退什么的,有啥区别?你只不过用一个flag把可能的值加了一倍而已,但是代码量更大。如果你强调smallint本身的值空间可能不够用,把version字段数据类型设为bigint就能增加何止上亿倍的值空间了,这样不也是简单的溢出就设0就能解决吗?######回复

@乌龟壳 : 你说的情况多个请求到达临界点就可能发生,而我说的配合flag做法,得跨过80多亿次,显然我的做法更严谨,让乐观锁更有意义.######回复

@乌龟壳 : 你说的情况发生的可能性实在太大了,跟我那个没法比,你没必要在这点上狡辩.你如果不考虑临界点问题,那乐观锁本来就没有了意义."

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值