数据库:锁机制、触发器、存储过程

一、锁机制

为什么需要锁机制?
我们的数据库是一个多客户端的程序,允许多个客户端同时连接同一个数据库,处理时会出现并发情况,我们就需要加锁来控制了。

锁机制:并发处理时保证数据完整性

1.1MyISAM中的锁:表锁

表锁:将整张表的数据都锁定,粒度大。 MyISAM会在底层自动加读锁或写锁。 例如:A在读取该数据,读取过程中,B想要修改该数据,为了保证数据完整性对其进行加一个读锁(lock table A read),将整张表的数据都锁定了,B再修改时则堵塞;当我们释放读锁(unlock tables),B立马执行成功。
数据库:锁机制、触发器、存储过程
①MyISAM中读锁read(共享读锁):select后自动加读锁。
例如:我们执行该条语句,MyISAM存储引擎拿到这条SQL语句首先加一个读锁,再执行查询操作,查询成功,最后进行读锁释放。
数据库:锁机制、触发器、存储过程
②MyISAM中写锁write(独占写锁):insert、delete、update后自动加读锁。
例如:我们执行该条语句,MyISAM存储引擎拿到这条SQL语句首先加一个写锁,其它链接不能进行查询,修改,直至写锁成功释放。
数据库:锁机制、触发器、存储过程

注意:
1.读锁共享:一张表上有多个读锁可以共存。
2.读锁和写锁不能共存:如果一张表上有读锁,另一个链接再给这张表上加写锁是不允许的。
3.写锁和写锁不能共存:如果一张表上有写锁,另一个链接再给这张表上加写锁是不允许的,写锁独占这张表。
数据库:锁机制、触发器、存储过程
 

1.2InnoDB中的锁:行锁

行锁:将一行数据锁定,粒度小。 例如:A读取第一行数据,此时B修改第二行数据,这两行数据没有任何联系,用表锁的话将整张表都锁定了效率就十分低;此时使用行锁效率会提高很多,A加了一个读锁,B修改时并没有影响直接写入,可以并发执行了。
数据库:锁机制、触发器、存储过程
①InnoDB中select不加锁:有没有锁都可以读取数据,并且有事务保持隔离性。

②InnoDB中读锁read(共享锁):
例如:InnoDB同一行可以加多个读锁。
数据库:锁机制、触发器、存储过程

③InnoDB中写锁write(排它锁):insert、delete、update后自动加读锁。只给一行数据加索,并不影响其它行数据处理。
数据库:锁机制、触发器、存储过程
例如:InnoDB支持事务,InnoDB每一个SQL都当成事务来处理,事务执行完成后会将所有锁都释放掉;我们执行该条语句,我们为第一行数据加上了写锁,遇到分号结束事务,其它链接可以进行修改。我们也可以将事务的自动提交修改为0:只有给出commit后事务才算完成,commit没提交之前其它链接不可修改。
数据库:锁机制、触发器、存储过程
注意:
1.同一行数据,读锁和读锁可以共存。
2.同一行数据,读锁和写锁不可以共存。
3.同一行数据,写锁和写锁不可以共存,排斥其它所有锁。

InnoDB也支持表锁。什么时候用到表锁,什么时候用到行锁呢?
InnoDB上索引查询用到行锁;非索引查询用到表锁。
数据库:锁机制、触发器、存储过程

1.3悲观锁

悲观锁:认为每个操作可能都会出现错误,每次提前加锁处理,保证后面的处理都是正确的。
属于悲观锁的:MyISAM的表锁,InnoDB中的行锁。

1.4乐观锁

乐观锁:认为每个操作可能都是正确的,出现问题的时候在加锁,保证处理也是正确的,好处是没有加锁解锁开销。 一般通过添加版本标识来处理。

       例如:这里有一个数据"zhangsan",数据进入后,自动添加一个0版本标识。并发情况下,A链接进行查询,查询前先拿到版本标识0,A在查询中B链接对其进行修改,B第一次拿到版本标识,B进行修改,修改成功再拿一次版本标识,进行匹配,若匹配成功认为其它链接没有修改这个数据,版本标识+1;若匹配失败,认为其他链接在修改数据中将链接发生变动,update执行失败。A再进行匹配,A第二次拿到版本标识发现为1,其查询过程中有数据被修改,select失败。
数据库:锁机制、触发器、存储过程

1.5意向锁

意向锁:防止死锁出现。 表锁粒度大,不容易发生死锁;行锁粒度小,容易发生死锁。
       例如:在表进行处理的时候,先加一个意向锁,所有的意向锁都可以共存。若该表上已经存在了一个意向读锁,查询操作也需要加一个意向读锁,再将我们添加的意向读锁与表上有的锁进行匹配。满足兼容规则,该操作语句加上读锁后不会产生死锁情况,允许加读锁;不满足兼容规则加上读锁可能会产生死锁情况,需要等待,直到满足兼容规则。
数据库:锁机制、触发器、存储过程
意向锁详解

1.6间隙锁

间隙锁:解决幻读问题。
       例如:我们id字段存储了1,2,3,4,5;执行select语句,查询结果为4,5。在一个事务中不是之间完成的,事务没有条件前会给4,5加上一个间隙锁,在这个结果的左边和右边分别加上间隙锁,又将4,5锁定。此时再添加6进去再执行查询,结果只会出现4,5,防止了幻读问题出现。
数据库:锁机制、触发器、存储过程

二、触发器

触发器: 当一个事件(操作)到来,触发器触发去执行另外一系列操作,触发器的类型通过触发事件+触发事件决定触发器的类型。一张表中,同类型的触发器只允许存在于一个,最多能创建6个触发器。

创建触发器:creat trigger 触发器名

哪些事件可以触发触发器:
1.insert类型触发器:insert可以触发,load(大批量插入)也可以触发,replace(先删除再插入形式实现替换)
2.delete类型触发器:delete触发。
3.update类型触发器:update触发,truncate删除。

例如:当我们统计一张表的数据个数时,每插入一个数据,触发器将记录中个数加1;删除一个数据,触发器将记录中个数减1。触发事件事件有两种:before与after。触发事件只有:insert,delete,update才能触发触发器。
数据库:锁机制、触发器、存储过程

三、存储过程

存储过程:一系列特定的流程写成存储过程保持下来,下次执行只需要调用来直接使用。

存储过程与存储函数区别:存储过程有多个返回值,通过call调用;存储函数只有一个返回值,通过select调用。

创建存储过程:create proceduce 存储过程名(形参列表)
数据库:锁机制、触发器、存储过程
形参列表构成:参数属性(IN OUT INOUT),参数名称,参数类型。
IN:输入型参数,值传递。
OUT:输出型参数,做数据输出使用。
INOUT:输入输出型参数,引用。
数据库:锁机制、触发器、存储过程