精华内容
下载资源
问答
  • 数据库加锁

    2020-11-05 16:07:19
    数据库的操作中也有相同的问题,当两个线程同时对一条数据进行操作,为了保证数据的一致性,就需要数据库的锁机制。每种数据库的锁机制都自己的实现方式,mysql作为一款工作中经常遇到的数据库,它的锁机制在面试...
    • 概述

       锁机制在程序中是最常用的机制之一,当一个程序需要多线程并行访问同一资源时,为了避免一致性问题,通常采用锁机制来处理。在数据库的操作中也有相同的问题,当两个线程同时对一条数据进行操作,为了保证数据的一致性,就需要数据库的锁机制。每种数据库的锁机制都自己的实现方式,mysql作为一款工作中经常遇到的数据库,它的锁机制在面试中也经常会被问到。所以本文针对mysql数据库,对其锁机制进行总结。
      

    mysql的锁可以分为服务层实现的锁,例如Lock Tables、全局读锁、命名锁、字符锁,或者存储引擎的锁,例如行级锁。InnoDB作为MySQL中最为常见的存储引擎,本文默认MySQL选择InnoDB作为存储引擎。
    锁的分类按照特性有多种分类,常见的比如显式锁和隐式锁;表锁和行锁;共享锁和排他锁;乐观锁和悲观锁等等。

    服务级别锁

    表锁
     表锁可以是显式也可以是隐式的。显示的锁用Lock Table来创建,但要记得Lock Table之后进行操作,需要在操作结束后,使用UnLock来释放锁。Lock Tables有read和write两种,Lock Tables…Read通常被称为共享锁或者读锁,读锁或者共享锁,是互相不阻塞的,多个用户可以同一时间使用共享锁互相不阻塞。Lock Table…write通常被称为排他锁或者写锁,写锁或者排他锁会阻塞其他的读锁或者写锁,确保在给定时间里,只有一个用户执行写入,防止其他用户读取正在写入的同一资源。

    1. Lock Tables…READ不会阻塞其他线程对表数据的读取,会阻塞其他线程对数据变更
    2. Lock Tables…WRITE会阻塞其他线程对数据读和写
    3. Lock Tables…READ不允许对表进行更新操作(新增、删除也不行),并且不允许访问未被锁住的表
    4. Lock Tables…WRITE允许对被锁住的表进行增删改查,但不允许对其他表进行访问

    IInnoDB锁

    乐观锁和悲观锁

    • 悲观锁:指悲观的认为,需要访问的数据随时可能被其他人访问或者修改。因此在访问数据之前,对要访问的数据加锁,不允许其他其他人对数据进行访问或者修改。上述讲到的服务器锁和InnoDB锁都属于悲观锁。
    • 乐观锁:指乐观的认为要访问的数据不会被人修改。因此不对数据进行加锁,如果操作的时候发现已经失败了,则重新获取数据进行更新(如CAS),或者直接返回操作失败。

    超卖问题解决
    1.使用mysql数据库的锁机制。在事务中使用 for update 语句,在事务处理完成之后释放这一条数据。

    
    public function mysqlLock(){
        $goods_id = 26545;
        $sku_id = 26545;
        $price = 300;
        $user = '';
        StoreOrderModel::startTrans();
        $nums = StoreOrderModel::where(['id'=>1])->field('number')->lock(true)->find();
        $nums = $nums['number'];
        if($nums > 0){
            $item['goods_id'] = $goods_id;
            $item['sku_id'] = $sku_id;
            $item['number'] = $nums;
            $item['price'] = $price;
            $item['user'] = $user;
            $id = StoreModel::insertGetId($item);
            if($id){
                StoreOrderModel::where(['id'=>1])->setDec('number');
                StoreOrderModel::commit();
            }else{
                StoreOrderModel::rollback();
            }
        }else{
            echo "没有库存了";
        }
    }
    

    2.使用redis队列

    public function  eq_start(){
     
        $redis = ResRedisModel::getinstance();
        $nums = $redis->lSize('store');
        $goods_id = 26545;
        $sku_id = 26545;
        $number = 1;
        $price = 300;
        $user = '';
     
        if($nums > 0){
            $user = $redis->rPop('store');
            if($user){
                $item['goods_id'] = $goods_id;
                $item['sku_id'] = $sku_id;
                $item['number'] = $number;
                $item['price'] = $price;
                $item['user'] = $user;
                StoreModel::insertGetId($item);
                echo '抢购成功!';
            }else{
                echo '抢购失败!';
            }
        }else{
            echo '抢购失败!';
        }
    }
    
    展开全文
  • MySQL数据库加锁实战总结

    千次阅读 2020-12-26 14:56:02
    不会阻塞update不存在的记录 会阻塞delete已经存在的记录,不会阻塞delete不存在的记录 会阻塞insert任意记录 这个例子其实可以很好的说明,数据库加锁针对的是索引,而不是记录。比如上面d字段没有索引,不管你...

    基础

    默认拥有MySQL基础,并且对MySQL事务有一定了解,比如:MVCC快照读,当前读(lock in share mode/for update),间隙锁等知识

    img

    索引组织表

    先理解下索引组织表。

    img辅助索引

    img聚集索引

    Innodb中的索引数据结构是 B+ 树,数据是有序排列的,从根节点到叶子节点一层层找到对应的数据。普通索引,也叫做辅助索引,叶子节点存放的是主键值。主键上的索引叫做聚集索引,表里的每一条记录都存放在主键的叶子节点上。当通过辅助索引select 查询数据的时候,会先在辅助索引中找到对应的主键值,然后用主键值在聚集索引中找到该条记录。举个例子,用name=Alice来查询的时候,会先找到对应的主键值是18 ,然后用18在下面的聚集索引中找到name=Alice的记录内容是 77 和 Alice。

    表中每一行的数据,是组织存放在聚集索引中的,所以叫做索引组织表。

    了解索引数据结构的目的是为了说明,行锁是加在索引上的。

    初始数据

    CREATE TABLE `t` (
    	`id` INT ( 11 ) NOT NULL,
    	`c` INT ( 11 ) DEFAULT NULL,
    	`d` INT ( 11 ) DEFAULT NULL,
    	PRIMARY KEY ( `id` ),
    	KEY `c` ( `c` ) 
    ) ENGINE = INNODB;
    
    INSERT INTO t
    VALUES
    	( 0, 0, 0 ),
    	( 5, 5, 5 ),
    	( 10, 10, 10 ),
    	( 15, 15, 15 ),
    	( 20, 20, 20 ),
    	( 25, 25, 25 );
    

    参考规则

    来源于极客时间MySQL实战45讲,大家可以根据这个规则理解我下面的例子,下面大部分是我自己另外总结的

    总结的加锁规则里面,包含了两个“原则”、两个"优化"和一个"bug"。
    
    1.原则1:加锁的基本单位是next-key lock。 希望你还记得,next-key lock是前开后闭区间。
    2.原则2:查找过程中访问到的对象才会加锁。
    3.优化1:索引上的等值查询,给唯一索引加锁的时候,next-key lock退化为行锁。
    4.优化2:引上的等值查询,向右遍历时且后-个值不满足等值条件的时候,next-key lock退化为间隙锁。
    5.一个bug:唯一引上的范围查询会访问到不满足条件的第一个值为止。
    

    一、update/delete没有索引的记录

    说明:delete/update操作结果其实是一样的,所以只专门讲解update即可,delete不再累赘描述

    update 没有索引且存在的记录/update没有索引且不存在的记录/update全表

    事务1事务2
    BEGIN;
    UPDATE t SET d=999 WHERE d=99(update 没有索引且存在的记录)
    或者
    UPDATE t SET d=999 WHERE d=0(update没有索引且不存在的记录)
    或者
    UPDATE t SET d=999(update全表)
    SELECT * FROM t WHERE id=0 LOCK IN SHARE MODE/FOR UPDATE(会阻塞当前读(for update/lock in share mode ))
    SELECT * FROM t (不会阻塞普通/快照读)
    UPDATE t SET c=222 WHERE id=0(会阻塞update已经存在的记录)
    UPDATE t SET c=222 WHERE id=66(不会阻塞update不存在的记录)
    DELETE FROM t WHERE id=0(会阻塞delete已经存在的记录)
    DELETE FROM t WHERE id=66(不会阻塞delete不存在的记录)
    INSERT INTO t(id, c, d) VALUES (111, 22, 10)(会阻塞insert)
    • 会阻塞当前读(for update/lock in share mode ),不会阻塞普通/快照读

    • 会阻塞update已经存在的记录,不会阻塞update不存在的记录

    • 会阻塞delete已经存在的记录,不会阻塞delete不存在的记录

    • 会阻塞insert任意记录

    这个例子其实可以很好的说明,数据库加锁针对的是索引,而不是记录。比如上面d字段没有索引,不管你update记录是否存在,都会锁住全表!!!

    二、update/delete有唯一索引的记录

    说明:delete/update操作结果其实是一样的,所以只专门讲解update即可,delete不再累赘描述

    前提:这里针对的是id这个主键唯一索引

    1、update有唯一索引且不存在的记录

    select普通读/快照读和当前读都不阻塞,update和delete也不阻塞,只会阻塞insert操作,具体如下:

    1、比如:update的20-25之间的22,UPDATE t SET d=999 WHERE id=22

    会阻塞insert前一个记录到后一个记录之间的间隙(20,25)—注意:这里针对是id在这个区间

    2、比如:update25以后的记录,UPDATE t SET d=999 WHERE id=66

    会阻塞(25,66],(66,+∞]—注意:这里针对是id在这个区间

    2、update有唯一索引且存在的记录

    主事务操作:UPDATE t SET d=999 WHERE id=15

    其他事务只会阻塞当前行的相关操作:

    • select当前读:SELECT * FROM t WHERE id=15 LOCK IN SHARE MODE/FOR UPDATE
    • UPDATE t SET d=999 WHERE id=15
    • DELETE from t WHERE id=15

    不阻塞insert操作(除了当前id=15以外的),不会加上间隙锁;不阻塞普通读/快照读

    三、update/delete有普通索引的记录

    说明:delete/update操作结果其实是一样的,所以只专门讲解update即可,delete不再累赘描述

    前提:这里针对的是c字段这个普通索引,也就是可能重复,一个索引对应多条记录

    1、update有普通索引且不存在的记录

    这个和唯一索引的区别其实差不多

    select普通读/快照读和当前读都不阻塞,update和delete也不阻塞,只会阻塞insert操作,具体如下:

    1、如果update的20-25之间的22,UPDATE t SET d=999 WHERE c=22

    只会阻塞insert前一个记录到后一个记录之间的间隙[20,25)—注意:这里针对是c字段在这个区间,和上面唯一索引不同的是包括了20

    2、如果update25以后的记录,UPDATE t SET d=999 WHERE c=66

    会阻塞(25,66],(66,+∞]—注意:这里针对是c字段在这个区间

    2、update有普通索引且存在的记录

    首先在原来的数据上再插入几条数据,只是为了说明普通索引可能会有一条索引对应多条记录的情况:比如索引25对应三条实体记录,分别是id为25,30,35

    INSERT INTO t
    VALUES
    	( 30, 25, 30 ),
    	( 35, 25, 35 );
    

    主事务操作:UPDATE t SET d=999 WHERE c=25

    其他事务会阻塞c字段索引25对应的所有记录(id=25/30/35)的相关操作:

    • select当前读:SELECT * FROM t WHERE id=25/30/35 LOCK IN SHARE MODE/FOR UPDATE
    • UPDATE t SET d=999 WHERE id=25/30/35
    • DELETE from t WHERE id=25/30/35
    • 会阻塞insert所有索引c字段设置为(20,25]和(25,30)之间的插入,如:INSERT INTO t VALUES ( 100, 25, 30 )INSERT INTO t VALUES ( 100, 22, 30 )INSERT INTO t VALUES ( 100, 27, 30 )

    不阻塞普通读/快照读

    四、select lock in share mode/for update没有索引的记录

    1、select lock in share mode

    select lock in share mode不会阻塞select lock in share mode操作,其他跟第一点的update/delete相同,也就是读锁不会阻塞读锁,只会阻塞写锁

    • 会阻塞当前读中的for update,不会阻塞lock in share mode,不会阻塞普通/快照读

    • 会阻塞update已经存在的记录,不会阻塞update不存在的记录

    • 会阻塞delete已经存在的记录,不会阻塞delete不存在的记录

    • 会阻塞insert

    跟第一点不一样的就是不会阻塞select lock in share mode

    2、select for update

    select for update阻塞的结果跟第一点的update/delete一模一样,因为本质也是一样的,全表加锁,并且写锁会阻塞读锁和写锁

    • 会阻塞当前读(for update/lock in share mode ),不会阻塞普通/快照读

    • 会阻塞update已经存在的记录,不会阻塞update不存在的记录

    • 会阻塞delete已经存在的记录,不会阻塞delete不存在的记录

    • 会阻塞insert

    五、select lock in share mode/for update有唯一索引的记录

    对于select for update,结果跟update/delete一模一样,也就是跟第二点一样;

    对于select lock in share mode,跟第二点不一样的就是不会阻塞select lock in share mode

    六、select lock in share mode/for update有普通索引的记录

    对于select for update,结果跟update/delete一模一样,也就是跟第三点一样;

    对于select lock in share mode,跟第三点不一样的就是不会阻塞select lock in share mode

    特别的:

    除了上面的规则外,有个特例,SELECT id,c FROM t WHERE c=5 LOCK IN SHARE MODE 这个查询使用覆盖索引,并不需要访问主键索引(也就是不需要再通过主键索引去回表查询其他字段的值),所以主键索引上没有加任何锁,所以可以执行这个操作 UPDATE t SET d=2232 WHERE c=5

    而对于上面第五点的唯一主键索引,会锁住整行,因为聚簇索引存储了整行记录

    七、insert操作

    比如INSERT INTO t(id, c, d) VALUES (66, 10, 12),这里会阻塞id=66这一行,别的地方无法insert id=66这个操作;

    由于c字段上有索引,所以也会阻塞c字段索引对应的update/delete操作,比如UPDATE t SET d=66 WHERE c=10;不会阻塞c=10字段对应的insert,比如INSERT INTO t(id, c, d) VALUES (666, 10, 12)

    展开全文
  • 准备用终端解压发现报错dpkg:错误:另外一个进程已经为 dpkg 状态数据库 加锁 是由于同时用软件中心打开了,结束中心进程并重启电脑即可解压,或者关闭所有进程终端输入sudo rm /var/lib/dpkg/lock,再不行删除重新...

    今天在Ubuntu的火狐浏览器上下载了vscodehttps://code.visualstudio.com/Download
    准备用终端解压发现报错dpkg:错误:另外一个进程已经为 dpkg 状态数据库 加锁
    是由于同时用软件中心打开了,结束中心进程并重启电脑即可解压,或者关闭所有进程终端输入sudo rm /var/lib/dpkg/lock,再不行删除重新下载,emmmm

    最后,在火狐下载时选择保存文件即可

    1. 防止同时开启两个进程运行
    2. 下载的东西可以直接在**/home/download**找到
      解压教程:在Ubuntu上安装vsCode
    展开全文
  • 在终端运行dpkg命令的时候提示dpkg错误:另外一个进程已为dpkg状态库加锁 原因可能是某处执行了apt-get命令或者某处也执行了dpkg命令或者很多奇奇怪怪的情况 解决方法很简单。。你可以选择重启 23333 ...

    在终端运行dpkg命令的时候提示 dpkg错误:另外一个进程已为dpkg状态库加锁

    原因可能是某处执行了apt-get命令或者某处也执行了dpkg命令或者很多奇奇怪怪的情况

    解决方法很简单。。你可以选择重启 23333   

    或者sudo rm /var/lib/dpkg/lock 即可
    --------------------- 
    作者:围巾的ACM 
    来源:CSDN 
    原文:https://blog.csdn.net/qq_21057881/article/details/78975052 
    版权声明:本文为博主原创文章,转载请附上博文链接!

     

    执行修复

    sudo dpkg --configure -a
    展开全文
  • 分析了客户-服务器模式存在的缺点和中小型企业商务信息管理网络系统对数据库管理的通用要求,并通过对网络数据库相关理论的探讨,提出了一种分布式数据库加锁与刷新机制。
  • ubuntu:dpkg:错误:另一个进程已经为dpkg状态数据库加锁 在使用qq和网易云linux版本的时候,从官网下载好rpm包,然后通过终端安装时,会出现这个错误,盲猜应该是dpkg进程被占用。 解决办法: 1.重启电脑 2.` sudo ...
  • 一、问题描述  平时喜欢边听歌边敲代码(有种拯救世界的感觉),windows时一直用网易云,换了linux非常不方便,所以想给我的ubuntu(16.04)装一个。去官网找了一下,还真有linux版的,还特别标明是ubuntu 16.04...
  • 数据库加锁操作

    千次阅读 2018-11-15 18:07:57
    数据库的加锁操作 从事一个项目,需要考虑数据的安全性,之前对于数据库这部分的数据操作学习的比较零散,由于手头的项目,...数据库加锁: 简单的意思就是对于在执行一个操作(比如修改)时,对这个操作的对象加...
  • 数据库加锁操作

    2015-03-23 13:05:00
    具体数据库加锁知识大家可以百度之,不过这里不需要太多高深的加锁知识,只需要一点就是写锁 写锁是神马捏?具体来说就是一种排他锁,当写的时候不允许其他程序写,这样就可以保证数据一致性了。OK了,这就够了,...
  • 1,执行 sudo rm /var/lib/dpkg/lock 2,然后执行修复 sudo dpkg --configure -a
  • 以下方式任选一个即可:1、重启系统2、执行(这种方式不要尝试,系统很容易挂)sudo rm /var/lib/dpkg/lock然后执行修复sudo dpkg –configure -a
  • NULL 博文链接:https://lchshu001.iteye.com/blog/1461841
  • 如何对行 表 数据库加锁   android 多线程数据库读写分析与优化   (转)SQLite的事务和锁   SQLite多线程下的并发操作  
  • Java 和 数据库进行加锁方式

    千次阅读 2018-12-29 16:37:36
    //在sql语句后加 for update就加上了锁,在查询的时候进行加锁,在加锁后不能进行查询。提交时候后其他人才能查询。 public static int generate(String tableName){ //使用数据库的悲观锁for update ...
  • 数据库加锁的知识收藏 关于数据库加锁的知识
  • SQLServer 数据库加锁的知识

    千次阅读 2011-09-19 09:50:49
    关于 SQLServer 数据库加锁的知识 LockType 属性 指示编辑过程中对记录使用的锁定类型。 设置和返回值 设置或返回以下某个LockTypeEnum 的值。 常量 说明 adLockReadOnly 默认值,只读。无法更改数据。 ...
  • JAVA程序对MYSQL数据库加锁实验

    万次阅读 2010-09-13 14:11:00
     在对aa1加锁时,必须把别名加上去(lock tables aa1 as byname_table read)  在同一个会话中.必须使用别名进行查询.  在不同的会话中.可以不需要使用别名进行查询.  5.在多个会话中可以对同一个表进行lock read...
  • 数据库中的共享锁与排它锁 为什么要加锁 共享锁 用法 排他锁 用法 加锁原则 数据库中的乐观锁与悲观锁 悲观锁 悲观锁实现方式 乐观锁 乐观锁实现方式 如何选择乐观锁还是悲观锁 数据库中的共享锁与排它锁 共享锁(S...
  • 数据库如何加锁?锁是用来干嘛的?

    万次阅读 热门讨论 2020-08-12 17:57:33
    文章目录数据库中的共享锁与排它锁为什么要加锁共享锁用法排他锁用法加锁原则数据库中的乐观锁与悲观锁悲观锁悲观锁实现方式乐观锁乐观锁实现方式如何选择乐观锁还是悲观锁 数据库中的共享锁与排它锁 共享锁(S锁)...
  • 对于多个用户同时提交表单,并且同时向数据库中得到表单ID,我是这样解决的: mysql_query("lock tables po read"); mysql_query("lock tables po write"); mysql_query("update po set id=id +1"));// ...
  • 公司DBA 的开发手记 开数据库加锁与性能分析 很值得一看
  • 因读时不加锁,所以不会阻塞其他事物在相同记录上加 X锁来更改这行记录。 2.写不影响读:事务以排他锁的形式修改原始数据,当读取的行正在执行 delete 或者 update 操作,这时读取操作不会因此去等待行上锁的释放。...
  • U8数据库加锁工具.rar

    2010-05-28 18:46:22
    U8数据库加锁工具.rarU8数据库加锁工具.rar
  • sql语句对数据库表进行加锁和解锁

    万次阅读 2018-06-29 22:56:21
    锁是数据库中的一个非常重要的概念,它主要用于多用户环境下保证数据库完整性和一致性。 我们知道,多个用户能够同时操纵同一个数据库中的数据,会发生数据不一致现象。即如果没有锁定且多个用户同时访问一个数据库...
  • create table t1 select 锁创建的新表全表,然后select渐进加锁。大表备份锁全表。 (似乎是for UPDATE) 备份表格的时候,由于读写量很大,会导致在备份的时间内锁表。 创建新字段、修改表格结构的时候会导致其他...
  • mysql数据库的锁有多少种,mysql中怎么加锁

    万次阅读 多人点赞 2019-03-03 15:09:45
    数据库锁定机制简单来说,就是数据库为了保证数据的一致性,而使各种共享资源在被并发访问变得有序所设计的一种规则。对于任何一种数据库来说都需要有相应的锁定机制,所以MySQL自然也不能例外。MySQL数据库由于其...
  • 从数据库MYSQL.innodb中读取一条数据,然后进行相应操作A,回写这条数据到数据库,因为操作A涉及时间较长,并且会需要其他数据库操作支持,这样数据库加锁容易造成冲突,请问该如何进行设计呢?
  • 数据库加锁的问题

    2018-11-06 09:24:40
    我一个表,大概是以下的简化结构 列名 f1 f2 ________________ 0 0 1 1 2 0 行数比较多,现在要执行的操作是读取f2=0的最小的f1记录,然后修改f2=1 请问怎么加锁效率最高
  • 数据库】MySQL 加锁处理分析

    千次阅读 多人点赞 2020-04-07 15:28:30
    MySQL/InnoDB的加锁分析,一直是一个比较困难的话题。我在工作过程中,经常会有同事咨询这方面的问题。同时,微博上也经常会收到MySQL锁相关的私信,让我帮助解决一些死锁的问题。本文,准备就MySQL/InnoDB的加锁...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 116,158
精华内容 46,463
关键字:

数据库加锁