当前位置:   article > 正文

如何避免事务造成的锁表?以及如何解决表锁_事务锁表

事务锁表

一、什么是锁表?

​ 在数据库里,同一个数据可能有多个人来读取或更改,为了防止更改的时候别人也同时更改,这里一般要锁住表不让别人改,锁表发生在insert update 、delete 中。

二、产生锁表的原因有哪些?

​ 锁表的原理是数据库使用独占锁机制,当执行insert,update,delete的语句时,对表进行锁住,直到发生commite 或者 回滚 或者退出数据库用户,insert时全表锁,因为要生成主键字段、索引等等,update是行级锁
不同索引的锁机制

  • myisam,锁表

  • innodb, 成功使用索引时锁行,否则锁表

  • 表级锁 开销小,吞吐量会减小

  • 行级锁 消耗大,吞吐量也大

  • MyISAM只支持表级锁;InnoDB支持行级锁(分为共享锁与排它锁),可以使用表锁;

  • 加锁和并发没什么关系,innodb一般情况下走索引或者主键更新都是锁行,其余都是锁表,在并发的时候可以加select for update手工锁
    产生锁表的原因:

    第一、 A程序执行了对 tableA 的 insert ,并还未 commite时,B程序也对tableA 进行insert 则此时会发生资源正忙的异常 就是锁表
    第二、锁表常发生于并发而不是并行(并行时,一个线程操作数据库时,另一个线程是不能操作数据库的,cpu 和i/o 分配原则)

第三、字段不加索引:在执行事务的时候,如果表中没有索引,会执行全表扫描,如果这时候有其他的事务过来,就会发生锁表!

第四、事务处理时间长:事务处理时间较长,当越来越多事务堆积的时候,会发生锁表!

第五、关联操作太多:涉及到很多张表的修改等,在并发量大的时候,会造成大量表数据被锁!

数据库锁表的必要条件:

1)互斥条件:指进程对所分配到的资源进行排它性使用,即在一段时间内某资源只由一个进程占用。如果此时还有其它进程请求资源,则请求者只能等待,直至占有资源的进程用毕释放。

2)请求和保持条件:指进程已经保持至少一个资源,但又提出了新的资源请求,而该资源已被其它进程占有,此时请求进程阻塞,但又对自己已获得的其它资源保持不放。

3)不剥夺条件:指进程已获得的资源,在未使用完之前,不能被剥夺,只能在使用完时由自己释放。

4)环路等待条件:指在发生死锁时,必然存在一个进程——资源的环形链,即进程集合{P0,P1,P2,···,Pn}中的P0正在等待一个P1占用的资源;P1正在等待P2占用的资源,……,Pn正在等待已被P0占用的资源。

三、如何解决表锁

(1)通过相关的sql语句可以查出是否被锁定,和被锁定的数据!

(2)为加锁进行时间限定,防止无限死锁!

(3)加索引,避免全表扫描!

(4)尽量顺序操作数据!

(5)根据引擎选择合理的锁粒度!

(6)事务中的处理时间尽量短!

1》减少insert 、update 、delete 语句执行 到 commite 之前的时间。具体点批量执行改为单个执行、优化sql自身的非执行速度
2》如果异常对事物进行回滚

  • 尽量使用较低的隔离级别
  • 精心设计索引,并尽量使用索引访问数据,使加锁更精确,从而减少锁冲突的机会。****
  • 选择合理的事务大小,小事务发生锁冲突的几率也更小。
  • 给记录集显示加锁时,最好一次性请求足够级别的锁。比如要修改数据的话,最好直接申请排他锁,而不是先申请共享锁,修改时再请求排他锁,这样容易产生死锁。
  • 不同的程序访问一组表时,应尽量约定以相同的顺序访问各表,对一个表而言,尽可能以固定的顺序存取表中的行。这样可以大大减少死锁的机会。
  • 尽量用相等条件访问数据,这样可以避免间隙锁对并发插入的影响。
  • 不要申请超过实际需要的锁级别;除非必须,查询时不要显示加锁。
  • 对于一些特定的事务,可以使用表锁来提高处理速度或减少死锁的可能。
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/387179
推荐阅读
相关标签
  

闽ICP备14008679号