zoukankan      html  css  js  c++  java
  • thinkphp中的lock与mysql的for update的使用注意事项

    一、数据库需要锁表的场景

    1. 场景1,对于资金和商品数量,非常重要。在同一时间内必须只有一个连接能够修改。
    2. 场景2:一个表A的值,依赖于表B的值,那么我在计算A更新值时,必须保证这个时间内,B表的值没有发生变化

    二、 在thinkphp框架锁表的实现

    1. 使用模型类,调用lock()方法, 参数true是全局范围的,false只是当前链接

    2. lock()调用会在sql语句后面,加上“for update”.

    3. lock生效的条件,必须方式一个事务中,可以使用所有表开启Db::stratTrans(),Db::commit()之后锁表结束

      • //单个表事务
        $user = new User();
        $db = $user->db(true);
        $db->startTrans();
        $res = $user->lock(true)->where(["id" => 1])->field('mobile,username')->find();
        sleep(3); // 休眠3秒,ID=1的行会锁表3秒
        $db->commit();
        
      • //多个表事务
        Db::stratTrans();
        User::lock(true)->where(["id" => 1])->field('mobile,username')->find();
        sleep(3); // 休眠3秒,ID=1的行会锁表3秒
        Db::commit();//或者回退也是户释放的,Db:rollback();
        
    4. lock生效过程中,其他的并发请求中的Update操作都会出于阻塞,等待的状态

    5. lock使用的注意事项,lock的条件,一定要用主键唯一索引键,否则容易导致,整个表被锁住,而导致其他服务都出于等待中。原因,下面会讲。

    三、mysql中for update

    1. for update是在数据库中上锁用的,可以为数据库中的行上一个排它锁。当一个事务的操作未完成时候,其他事务可以读取但是不能写入或更新。

    2. InnoDB默认是行级别的锁,当有明确指定的主键时候,是行级锁。否则是表级别。

    3. for update 仅适用于InnoDB,并且必须开启事务,在begin与commit之间才生效。

    4. 锁的具体实例,假设表foods ,存在有id跟name、status三个字段,id是主键,status有索引。

      1. 明确指定主键,并且有此记录,行级锁

        SELECT * FROM foods WHERE id=1 FOR UPDATE;
        SELECT * FROM foods WHERE id=1 and name=’咖啡色的羊驼’ FOR UPDATE;
        
      2. 明确指定主键/索引,若查无此记录,无锁

        SELECT * FROM foods WHERE id=-1 FOR UPDATE;
        
      3. 无主键/索引,表级锁。影响非常大

        SELECT * FROM foods WHERE name=’咖啡色的羊驼’ FOR UPDATE;
        
      4. 主键/索引不明确,表级锁。影响非常大

        SELECT * FROM foods WHERE id<>’3’ FOR UPDATE;
        SELECT * FROM foods WHERE id LIKE ‘3’ FOR UPDATE;
        
    5. for update nowait 锁住表或者锁住行,只允许当前事务进行操作(读写),其他事务被拒绝,事务占据的statement连接也会被断开

  • 相关阅读:
    java IO输入输出流实现文本复制
    java HashMap
    java TreeSet 实现存自定义不可重复数据
    java中的ArrayList 使得集合中的对象不重复
    java 多线程执行过程
    final关键字的使用
    java中==和equals的区别
    java面向对象理解
    java语言基础(变量和运算符)
    学习Java第一天,大致了解
  • 原文地址:https://www.cnblogs.com/qumogu/p/14826050.html
Copyright © 2011-2022 走看看