数据库之锁模块

锁出现的原因是为了处理并发问题。数据库并发需要使用事务来控制,事务并发问题需要数据库锁来控制,所以数据库锁是跟并发控制和事务联系在一起的。
 平时会经常看到或者听到数据库锁有“共享锁”,“排它锁”,“互斥锁”,“写锁”,“读锁”,“悲观锁”,“乐观锁”,“行级锁”,“表级锁”,“页级锁”等,同时我们还会常看到“丢失修改“,”不可重复读“,”读脏数据“这三个术语,下面开始介绍:

一、事务
事务是数据库恢复和并发控制的基本单位。他必须满足ACID(原子性;一致性;隔离性;持久性)
原子性:事务的操作要么同时成功,要么同时失败
一致性:事务的操作使得数据库从一个一致性状态转移到另一个一致性状态,例如转账,必须保持余额的总和不变
隔离性:一个事务的操作不会对另一个事务产生影响
持久性:事务对数据库的操作应当永久的保存在数据库中

二、乐观锁和悲观锁
并发控制一般采用三种方法,分别是乐观锁和悲观锁以及时间戳。
1、乐观锁:认为一个用户读数据的时候,别人不会去写自己所读的数据;乐观锁就是不做控制。
2、悲观锁:刚好相反,觉得自己读数据库的时候,别人可能刚好在写自己刚读的数据;悲观锁在读取数据的时候,为了不让别人修改自己读取的数据,就会先对自己读取的数据加锁,只有自己把数据读完了,才允许别人修改那部分数据,只有等自己的整个事务提交了,才释放自己加上的锁,才允许其他用户访问那部分数据。
3、时间戳:不加锁,通过时间戳来控制并发出现的问题。时间戳就是在数据库表中单独加一列时间戳,每次读出来的时候,把该字段也读出来,当写回去的时候,把该字段加1,提交之前 ,跟数据库的该字段比较一次,如果比数据库的值大的话,就允许保存否则不允许保存,这种处理方法虽然不使用数据库系统提供的锁机制,但是这种方法可以大大提高数据库处理的并发量,因为这种方法可以避免了长事务中的数据库加锁开销。

三、悲观锁中的排他锁和共享锁
共享锁又称为读锁,lock tables 表名 read。上了读锁之后可以进行读操作,不能写
排他锁又称写锁,lock tables 表明 write。排他锁是读锁和排他锁都不能加了。

四、活锁和死锁
并发控制会造成活锁和死锁,就像操作系统那样,会因为互相等待而导致。
活锁:指的是T1封锁了数据R,T2同时也请求封锁数据R,T3也请求封锁数据R,当T1释放了锁之后,T3会锁住R,T4也请求封锁R,则T2就会一直等待下去,这种处理方法就是采用“先来先服务”策略;
死锁:就是我等你,你又等我,双方就会一直等待下去,比如:T1封锁了数据R1,正请求对R2封锁,而T2封住了R2,正请求封锁R1,这样就会导致死锁,死锁这种没有完全解决的方法,只能尽量预防

预防死锁的方法
①一次封锁发,指的是一次性把所需要的数据全部封锁住,但是这样会扩大了封锁的范围,降低系统的并发度;
②顺序封锁发,指的是事先对数据对象指定一个封锁顺序,要对数据进行封锁,只能按照规定的顺序来封锁,
但是**这个一般不大可能**的。

系统如何判断出现死锁?

 毕竟出现死锁不能一直干等下去,要及时发现死锁同时尽快解决出现的死锁,诊断和判断死锁有两种方法,
 一是超时法,二是等待图法。
 超时法就是如果某个事物的等待时间超过指定时限,则判定为出现死锁;
 等待图法指的是如果事务等待图中出现了回路,则判断出现了死锁。对于解决死锁的方法,只能是撤销一个处理死锁代价最小的事务,释放此事务持有的所有锁,同时对撤销的事务所执行的数据修改操作必须加以恢复。

五、表级锁和行级锁
表级锁:对表进行访问时会封锁整张表,MyISAM默认使用的就是表级锁
行级锁:对表进行访问时,只会封锁表中部分行。InnoDB不走索引时用的表级锁,当使用索引时,用的行级锁。
MyISAM适用于查询比较频繁,多次使用count的场景,没有事务
InnoDB适用于增删改查都比较频繁的场景,支持事务且安全性较高

六、事务的隔离级别以及各级别下的并发访问问题
1、read uncommitted:最低事务隔离级别。在此事务隔离级别下会发生更新丢失的问题。
2、read committed:会发生脏读。即一个事务在操作时会读取到另一个事务还未提交的内容。
3、repeatable read:会发生不可重复读。事务A多次读取同一个数据,事务B在A的读取过程中修改了这一数据,导致A读到的数据不同。可能导致A利用该读取数据计算的结果不对。(侧重对同一数据的修改)
4、serializable:幻读,事务A再更新一个数据时,事务B突然加入一条新的数据,导致A更新成功多一条数据,类似出现幻觉。(侧重于新增和删除)

七、InnoDB可重复读下如何避免幻读?
表象:快照读
当前读主要是select…for update;selcet … in share mode;update;delete;insert
快照读:select
快照读读取到的不一定是最新的数据,可能是历史数据。创建快照读的时机非常重要
内在:next-key(行锁+gap锁)
1、如果where的条件全中,不加锁
2、where的条件部分中或者全不中,加Gap锁(如id=7不存在,会锁住7周围的间隙),Gap锁的是数据周围的区间,是左开右闭的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值