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'; 
  • 相关阅读:
    Centos7.2升级内核至3.10.0-957【转】
    部署一套完整的Kubernetes高可用集群(上)【转】
    Nginx配置中一个不起眼字符"/"的巨大作用,失之毫厘谬以千里【转】
    使用vmware搭建k8s集群【转】
    nginx的request body日志格式配置
    nginx漏洞修复:SSL/TLS 服务器瞬时 Diffie-Hellman 公共密钥过弱【原理扫描】【转】
    nginx:[warn] the "ssl" directive is deprecated, use the "listen ... ssl" directive instead
    linux系统删除分区
    Linux用户锁定、解锁及锁定查看
    innobackupex远程备份【转】
  • 原文地址:https://www.cnblogs.com/lz2017/p/10284865.html
Copyright © 2011-2022 走看看