zoukankan      html  css  js  c++  java
  • 数据库行锁,表锁

          锁主要用于多用户环境下保证数据库完整性和一致性。 我们知道,多个用户能够同时操纵同一个数据库中的数据,会发生数据不一致现象。即如果没有锁定且多个用户同时访问一个数据库,则当他们的事务同时使用相同的数据时可能会发生问题。这些问题包括:脏读、不可重复读和幻读

    脏读就是指当一个事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中,这时,另外一个事务也访问这个数据,然后使用了这个数据。因为这个数据是还没有提交的数据,那么另外一个事务读到的这个数据是脏数据,依据脏数据所做的操作可能是不正确的。(解决办法:Read Committed 读提交,保证只有当A事务提交了数据之后,B事务才能够读取数据)

    不可重复读是指在一个事务内,多次读同一数据。在这个事务还没有结束时,另外一个事务也访问该同一数据并提交。那么,在第一个事务中的两次读数据之间,由于第二个事务的修改,那么第一个事务两次读到的的数据可能是不一样的。这样就发生了在一个事务内两次读到的数据是不一样的,因此称为是不可重复读。(解决办法:加行锁,A事务在操作某几行数据的时候,B事务只能操作其他行的数据,加锁了的几行无法进行操作,这样就避免了两次读的不一致性。Mysql默认使用这种方法。    Repeatable Read可重复读)

    幻读是指当事务不是独立执行时发生的一种现象,例如第一个事务对一个表中的数据进行了修改,这种修改涉及到表中的全部数据行。同时,第二个事务也修改这个表中的数据,这种修改是向表中插入一行新数据。那么,就会发生第一个事务的用户发现表中还有没有修改的数据行,就好象发生了幻觉一样。(解决办法:只能对整个表加锁,开销最小,但是性能最低。  Serializable串行化)

    Read Uncommitted 不能避免脏读、不可重复读和幻读。

    --------------------------------------------------------------------------------------------------------------

    行级锁是Mysql中锁定粒度最细的一种锁,行级锁能大大减少数据库操作的冲突。行级锁分为共享锁和排他锁两种,本文将详细介绍共享锁及排他锁的概念、使用方式及注意事项等。

    共享锁(Share Lock)

    共享锁又称读锁,是读取操作创建的锁。其他用户可以并发读取数据,但任何事务都不能对数据进行修改(获取数据上的排他锁),直到已释放所有共享锁。

    如果事务T对数据A加上共享锁后,则其他事务只能对A再加共享锁,不能加排他锁。获准共享锁的事务只能读数据,不能修改数据。

    用法

    SELECT ... LOCK IN SHARE MODE;

    在查询语句后面增加LOCK IN SHARE MODE,Mysql会对查询结果中的每行都加共享锁,当没有其他线程对查询结果集中的任何一行使用排他锁时,可以成功申请共享锁,否则会被阻塞。其他线程也可以读取使用了共享锁的表,而且这些线程读取的是同一个版本的数据。

    排他锁(eXclusive Lock)

    排他锁又称写锁,如果事务T对数据A加上排他锁后,则其他事务不能再对A加任任何类型的封锁。获准排他锁的事务既能读数据,又能修改数据。

    用法

    SELECT ... FOR UPDATE;

    在查询语句后面增加FOR UPDATE,Mysql会对查询结果中的每行都加排他锁,当没有其他线程对查询结果集中的任何一行使用排他锁时,可以成功申请排他锁,否则会被阻塞。

    对于insert、update、delete(增删改),InnoDB会自动给涉及的数据加排他锁(X);对于一般的Select语句,InnoDB不会加任何锁。

    在mysql中有表锁,

    LOCK TABLE my_tabl_name READ;  用读锁锁表,会阻塞其他事务修改表数据。

    LOCK TABLE my_table_name WRITE; 用写锁锁表,会阻塞其他事务读和写。

    -----------------------------------------------------------------------------------------------------------------

    意向锁的作用就是“表明”加锁的意图:The main purpose of IX and IS locks is to show that someone is locking a row, or going to lock a row in the table。

    意向锁是表级锁,InnoDB中的两个表锁:

    意向共享锁(IS):表示事务准备给数据行加入共享锁,也就是说给一个数据行加共享锁前必须先取得该表的IS锁

    意向排他锁(IX):类似上面,表示事务准备给数据行加入排他锁,也就是说事务在一个数据行加排他锁前必须先取得该表的IX锁。

    意向锁是InnoDB自动加的,不需要用户干预。

    IX,IS是表级锁,不会和行级的X,S锁发生冲突。只会和表级的X,S发生冲突

    这两中类型的锁共存的问题

    考虑这个例子:

    事务A锁住了表中的一行,让这一行只能读,不能写。

    之后,事务B申请整个表的写锁。

    如果事务B申请成功,那么理论上它就能修改表中的任意一行,这与A持有的行锁是冲突的。

    数据库需要避免这种冲突,就是说要让B的申请被阻塞,直到A释放了行锁。

    数据库要怎么判断这个冲突呢?

    step1:判断表是否已被其他事务用表锁锁表
    step2:判断表中的每一行是否已被行锁锁住。

    注意step2,这样的判断方法效率实在不高,因为需要遍历整个表。
    于是就有了意向锁。

    在意向锁存在的情况下,事务A必须先申请表的意向共享锁,成功后再申请一行的行锁。

    在意向锁存在的情况下,上面的判断可以改成

    step1:不变
    step2:发现表上有意向共享锁,说明表中有些行被共享行锁锁住了,因此,事务B申请表的写锁会被阻塞。


    注意:申请意向锁的动作是数据库完成的,就是说,事务A申请一行的行锁的时候,数据库会自动先开始申请表的意向锁,不需要我们程序员使用代码来申请。

    ---------------------------------------------------------------------------------------------------------------






  • 相关阅读:
    28完全背包+扩展欧几里得(包子凑数)
    HDU 3527 SPY
    POJ 3615 Cow Hurdles
    POJ 3620 Avoid The Lakes
    POJ 3036 Honeycomb Walk
    HDU 2352 Verdis Quo
    HDU 2368 Alfredo's Pizza Restaurant
    HDU 2700 Parity
    HDU 3763 CDs
    POJ 3279 Fliptile
  • 原文地址:https://www.cnblogs.com/james111/p/7003076.html
Copyright © 2011-2022 走看看