乐观锁
mysql数据库中的
一般在操作数据的时候不认为会有数据冲突,只有在修改保存数据的时候,判断数据是否未修改过,有一个字段记录版本信息,修改保存之前判断一下与第一次取出的是否相等,相等则更新版本信息,否则就人为数据已经被就改过,放弃修改
悲观锁
mysql数据库中的
在操作数据的时候,认为会造成数据冲突,每次操作的时候都要通过获取锁才能对数据进行操作,消耗的时间比较多,悲观锁是数据库自己实现的,调用语句就可以,
要使用悲观锁要关闭数据库的自动提交属性,因为数据库默认使用autocommit模式(默认开启事务,一条语句执行完,自动提交)
悲观锁引出的两个概念共享锁和 排他锁 都属于悲观锁的类型
共享锁
又称为读锁,是读取操作的时候创建的锁,其他用户可以并发读取数据,但是任何事务都不能对数据进行修改(不能获取排他锁),支到释放共享锁,
如果事务A对数据B加了共享锁,其他的事务也只能对数据B再加上共享锁,不能加排他锁,获取共享锁的事务只能读取数据,不能修改数据。
LOCK IN SHARE MODE 在查询语句后面加上这个,mysql会对查询结果的每行加上共享锁,当没有其他线程对数据中的任意一行加排他锁时,可以成功申请共享锁,否则会阻塞,直至获取成功,或者超时,其他线程也可以读取并且加共享锁,获取的数据时同一版本数据
加上共享锁后,对于修改删除,添加操作会自动加排他锁,
排他锁
又称为写锁,加上写锁,其他事务不能在此期间修改读取数据
事务A对数据B加上写锁,事务A可以对数据进行读取跟修改,其他事务不能对数据加任务和锁,直到事务A释放锁,保证其他事务在事务A拥有锁之间不能读取跟修改数据,排他锁会阻塞所有的排他锁跟共享锁,
读取数据为什么要加读锁,防止数据在被读取期间,被别的线程加上写锁
行锁
mysql数据库中的
行锁又分为共享锁跟排他锁,给某一行加上锁,
行级锁都是基于索引的,如果sql语句没有使用索引就会使用表锁(主键就是索引)
行锁的共享锁跟排他锁和上边的类型一样
特点:请求大量的锁资源,速度慢,消耗大,不容易发生死锁,粒度小,锁冲突概率小,并发数高
表锁
行锁在没有使用索引的时候,就是表锁
在使用innoDB行锁的时候注意如果没有使用索引,就会变成表锁,两种锁都支持,
特点:资源少,速度快,容易发生死锁,粒度大,锁冲突概率大,并发数低
死锁
死锁是指两个或者两个以上的进程在执行过程中因为抢夺资源而产生的一种互相等待的现象,若无外力情况下,将无法推进下去,此时称系统处于死锁状态或者系统产生死锁,这些互相等待的进程成为死锁进程,由于资源占用是互斥的,当某个进程提出申请资源后,使得有关进程在无外力协助下,永远分配不到需求的资源而无法继续运行,这就产生了特殊现象死锁
其实就是多个进程,互相拿到对方请求的资源,而互相等待对方结束进程,导致无限等待,后来的进程什么也请求不到,事务等待超时,
接触进程的两种方法,查看是否锁表,查询进程,杀死进程。或者找到锁死的事务,杀死进程
产生死锁的四个必要条件
1.互斥条件,一个资源每次只能被一个进程使用
2.请求与保持条件,一个进程因请求资源而阻塞时,对已经获得的资源保持不放,
3.不剥夺条件,进程以获得的资源在未使用完之前,不能强行剥夺
4.循环等待条件,若干进程之间形成一种头尾相接的循环等待资源关系
可重入锁
可重入锁也叫递归锁,当一个处理外层函数需要加锁,内层函数也需要加锁,为了满足要求,出现的可冲入锁,可以记住获取锁的线程,可以每次获取本线程的锁,获取一下加一 释放减一,直至为0 彻底释放