zoukankan      html  css  js  c++  java
  • 关于数据库行锁与表锁的认识

    MySQL

    MySQL(InnoDB存储引擎)默认是自动提交事务的,所以这个测试,需要先将MySQL的autocommit设置为0,关闭自动提交,需要自己手动提交事务

    -- 关闭自动提交
    set autocommit=0;
    -- 开启事务
    begin;

    这里我主要针对的是悲观锁,其实也就是行锁和表锁,SQL 加上 FOR UPDATE 即可

    行锁

    这个时候,我们再开启一个客户端访问MySQL,输入同一条加锁的SQL查询

    这个时候是没有任何结果的,因为t_card表已经加锁了(这个时候其实加的是行锁),所以cardid=‘1’ 这一行的其他加锁操作是无效的

    但是不加锁查询这一条记录却是可以的

    也就是说虽然这一条记录所在的行被锁定了,但是并不影响我们正常的查询,当然了针对这一行的DML操作也是无效的

    那如果我们对除了cardid=‘1’ 的其他行操作会怎样呢?

    对于其他的行DML是完全没问题的,所以我在前面才说这是行锁,因为只有我们的cardid=‘1’的行被锁了

    好吧,我们放过cardid=‘1’这一行吧

    提交事务之后,另一边的加锁SQL才会生效

    表锁

    上面我们测试的只是行锁,那表锁,或者说怎样才会发生表锁?

    没错,我们不根据主键查询,而是查询所有的记录,MySQL就对整张表加锁了,这不就是表锁了嘛。对于这张表的任何记录进行DML都是无效的

    同时我们对于这张表的任何行进行加锁SQL操作是无效的,那普通的SQL查询又怎样呢?

    还好,这不妨碍我们的普通查询,毕竟查询是与锁这东西没什么缘分的

    结论

    只要有锁存在的地方(无论是一行还是整张表),我们对有锁的地方进行任何加锁SQL都是无效的,当然了DML也是无效的;但是我们的普通查询是没有问题的,同时对于没有锁的行也是可以进行DML操作的

    至于如何解除锁,可以查看这篇博客: https://zhengdl126.iteye.com/blog/1570865 。最后记得把MySQL的autocommit = 1

    Oracle

    Oracle是需要我们手动提交事务的,所以,我们不需要任何设置即可测试

    只有提交事务之后,另一边才会生效,同样的普通查询是没有问题的。如果不根据主键查询,就会锁整张表。最后的结论是与MySQL一致的

    查看哪张表被锁以及解锁

    -- 查看哪张表被锁
    SELECT object_name, machine, s.sid, s.serial#, logon_time, locked_mode
    FROM gv$locked_object l, dba_objects o, gv$session s 
    WHERE l.object_id = o.object_id 
    AND l.session_id = s.sid;
    
    -- 解锁(根据上边SQL查询结果得到sid和serial#)
    --alter system kill session 'sid,serial#'; 
    ALTER system kill session '23,1647'; 
  • 相关阅读:
    Data Base mysql备份与恢复
    java 乱码问题解决方案
    【知识强化】第二章 物理层 2.1 通信基础
    【知识强化】第二章 进程管理 2.2 处理机调度
    【知识强化】第二章 进程管理 2.1 进程与线程
    【知识强化】第一章 操作系统概述 1.3 操作系统的运行环境
    【知识强化】第一章 网络体系结构 1.1 数据结构的基本概念
    【知识强化】第一章 网络体系结构 1.2 计算机网络体系结构与参考模型
    【知识强化】第一章 网络体系结构 1.1 计算机网络概述
    【知识强化】第一章 操作系统概述 1.1 操作系统的基本概念
  • 原文地址:https://www.cnblogs.com/lz2017/p/10284865.html
Copyright © 2011-2022 走看看