在软件开发中,在高并发程序的情况下,为了保证一致性或者安全性,我们通常会通过加锁的方式来解决。在MySQL数据库中,同样存在这样的问题。一方面为了在很大程度上利用数据库的并发访问,另一方面又要保证每个用户都能以一致的方式读取和修改数据,所以锁机制介绍。在MySQL数据库中,锁的种类很多,但大致可以分为三类:全局锁、表级锁和行级锁。在这篇文章中,我们将简单地谈谈这三种类型的锁。全局锁全局锁是粒度比较大的锁,基本不能用。就像我们家的大门一样,它控制着整个数据库实例。全局锁是对整个数据库实例加锁,使整个数据库处于只读状态。MySQL提供了添加全局读锁的方法。该命令是Flushtableswithreadlock(FTWRL)。加锁后,整个数据库实例处于只读状态,与数据操作相关的命令将被挂起和阻塞,如数据更新语句、数据定义语句、更新类事务语句等。所以全局锁一般只用于全库备份,一般只用于存储引擎不支持一致性读的全库备份。例如,在使用不支持一致性读取的存储引擎进行全库备份时,需要使用MyISAM。全局锁和InnoDB引擎一样,在做数据库全量备份时不需要使用全局锁。表级锁表级锁是MySQL非常基本的一种加锁策略,也是开销最小的策略。它不会锁定整个数据库实例,而是锁定一个表。表级锁与全局锁相同。MySQL数据库提供了加锁命令:locktables...read/write。比如锁表t1读,t2写;命令,其他线程写t1和读写t2的语句会被阻塞。同时线程A在执行unlocktables之前只能进行读t1和读写t2的操作。连t1都不允许写,自然不能访问其他表。我们可以使用解锁表来主动释放锁。如果不使用,会在客户端断开连接时自动释放。表级锁定存在问题。如果一个查询正在遍历一个表中的数据,而另一个线程在执行过程中改变了表结构并删除了一个列,那么查询线程得到的结果与表结构不匹配。这是不可接受的。为了解决这个问题,MySQL5.5引入了元数据锁(metadatalock,MDL)。MDL被数据库自动锁定。对表进行增删改查时,加MDL读锁;在进行结构更改操作时,添加MDL写锁。MDL锁有以下两个特点:读锁不互斥,可以让多个线程同时对表进行增删改查。读写锁和写锁是互斥的,保证了改变表结构操作的安全性。因此,如果两个线程同时要向一张表中添加字段,则其中一个线程要等到另一个线程执行完后才会开始执行。行级锁行级锁,顾名思义,锁定数据库表中的行记录。行级锁可以在很大程度上支持并发处理,但同时也带来了很大的加锁开销。行级锁比较容易理解。比如事务A更新了一行,此时事务B也需要更新同一行,而更新必须等到事务A的操作完成。行级锁由每个存储引擎实现,并不是所有的存储引擎都支持行级锁。例如MyISAM引擎不支持行级锁,这意味着MyISAM存储引擎只能使用表级锁来控制并发。InnoDB引擎实现了行级锁,InnoDB存储引擎中实现了两种标准的行级锁:共享锁(SLock):允许事务读取一行独占锁(XLock):允许事务删除和更新arowofsharedlocks是compatiblelock是指当一个事务已经获取了r行的共享锁后,其他事务可以立即获得r行的共享锁,因为read没有改变r行的数据。独占锁是非兼容锁。如果一个事务要获取行r的排他锁,如果行r上有共享锁或排他锁,则必须等待其他事务释放行r上的锁。在InnoDB存储引擎中,默认使用一致性非锁行读取,即通过行多版本控制器读取行数据。我们可以对行显示共享锁和排它锁,语句如下:SELECT.....FORUPDATE:给读到的行记录加排他锁,其他事务想加就阻塞锁定到这些行。SELECT.....LOCKINSHAREMODE:给读行记录加共享锁,其他事务可以给加锁记录加共享锁,但是想加排他锁。将被阻止。以上就是MySQL数据库中锁的共享。希望本文对您的学习或工作有所帮助。如果觉得文章有用,请帮忙转发。谢谢。
