网站优化中的八门金“锁”

MySQL中的锁:
从锁定粒度上区分为:表级锁,页级锁,行级锁。

  • 表级锁:
    特点:开销小,加锁快;不会出现死锁;锁定粒度大,发生锁冲突的概率最高,并发度低。
    代表引擎是MyISAM引擎。
    表级锁定分为:表共享读锁(共享锁)与表独占写锁(排他锁)。
    注:
    开销小:指加锁资源消耗较少
    锁定粒度大:指锁的级别,最小的行级锁,最大的表锁。
    锁冲突高:因为针对整个表加锁,除非没有其他人操作否则冲突。
  • 页级锁(不详解)
    特点:优缺点介于表级锁和行级锁之间,粒度为相邻一组数据行。
    代表引擎是BDB引擎。
  • 行级锁:
    特点:开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突概率最低,并发度也最高。
    代表引擎是InnoDB引擎。InnoDB也支持表级锁,默认为行级锁
    行级锁分为:共享锁和排他锁
    注:
    死锁:两个进程同时操作一组数据,相互争夺控制权,造成相互等待若无外力不继续进行一直等待的现象,称之为死锁。
    当两个事务同时执行,一个锁住了主键索引,在等待其他相关索引。另一个锁定了非主键索引,在等待主键索引。这样就会发生死锁。发生死锁后,InnoDB一般都可以检测到,并使一个事务释放锁回退,另一个获取锁完成事务。
    行锁与表锁:InnoDB行锁是通过给索引上的索引项加锁来实现的,这一点MySQL与Oracle不同,后者是通过在数据块中对相应数据行加锁来实现的。InnoDB这种行锁实现特点意味着:只有通过索引条件检索数据,InnoDB才使用行级锁,否则,InnoDB将使用表锁

从保证数据一致性上区分:共享锁(表-读锁)、排他锁(表-写锁)

  • 共享锁(share lock)
    共享锁又称读锁,是读取操作创建的锁。其他用户可以并发读取数据,但任何事务都不能对数据进行修改(获取数据上的排他锁),直到已释放所有共享锁。MyISAM 存储引擎只支持表锁,MySQL 的表级锁有两种模式:表共享读锁(Table Read Lock)和表独占写锁(Table Write Lock)。
    对于读操作,可以增加读锁,一旦数据表被加上读锁,其他请求可以对该表再次增加读锁,但是不能增加写锁。(当一个请求在读数据时,其他请求也可以读,但是不能写,因为一旦另外一个线程写了数据,就会导致当前线程读取到的数据不是最新的了。这就是不可重复读现象)
    对表test_table增加读锁:
    LOCK TABLES test_table READ
    UNLOCK test_table
  • 排他锁(exclusive Lock)
    排他锁又称写锁,如果事务T对数据A加上排他锁后,则其他事务不能再对A加任任何类型的封锁。获准排他锁的事务既能读数据,又能修改数据。
    对于写操作,可以增加写锁,一旦数据表被加上写锁,其他请求无法在对该表增加读锁和写锁。(当一个请求在写数据时,其他请求不能执行任何操作,因为在当前事务提交之前,其他的请求无法看到本次修改的内容。这有可能产生脏读、不可重复读和幻读)
    读锁和写锁都是阻塞锁。读写同时默认写优先,即使后进也优先(默认)
    对表test_table增加写锁
    LOCK TABLES test_table WRITE
    UNLOCK test_table
  • 对于共享锁大家可能很好理解,就是多个事务只能读数据不能改数据,对于排他锁大家的理解可能就有些差别,排他锁指的是一个事务在一行数据加上排他锁后,其他事务不能再在其上加其他的锁。mysql InnoDB引擎默认的修改数据语句,update,delete,insert都会自动给涉及到的数据加上排他锁,select语句默认不会加任何锁类型,如果加排他锁可以使用select …for update语句,加共享锁可以使用select … lock in share mode语句。所以加过排他锁的数据行在其他事务种是不能修改数据的,也不能通过for update和lock in share mode锁的方式查询数据,但可以直接通过select …from…查询数据,因为普通查询没有任何锁机制。

PHP中的文件锁机制

  • 说明:文件锁机制一般在单独操作文件时看不到效果,需要多人同时操作(并发)。
  • 用途:若一个人在写入一个文件,另外一个人同时也打个了这个文件进行写入文件。
    这情况下,很难明确谁的操作为准。因此,这个时候我们引入锁机制。若用户A在写入或者读取这个文件的时候,将文件加上共享锁。我可以读,其他人也可以读。但是,其他人不可以写。我使用独占锁/排它锁。这个文件归我了,你们都别动,除非我将文件锁进行释放。
  • 锁类型:
    LOCK_SH 取得共享锁定(读取的程序)
    LOCK_EX 取得独占锁/排它锁定(写入的程序)
    LOCK_UN 释放锁定(无论共享或独占)
    LOCK_NB 当被锁定时,不阻塞,而是提示锁定。
    注:加锁必须释放

发表评论

电子邮件地址不会被公开。 必填项已用*标注