数据库锁全集

一、全局锁:

顾名思义,全局锁执行后,整个库都锁定。有读锁和写锁,加锁和解锁方式如下:
加锁:flush tables WITH READ LOCK;
解锁:UNLOCK TABLES;
使用场景:做全库的逻辑备份;

二、表级锁:

有读锁和写锁,加锁和解锁方式如下:

加锁:LOCK TABLES `role` READ;
解锁:UNLOCK TABLES;
使用场景:(1)读密集型;(2)写作不频繁的场景;(3)数据量不大的简单应用;(4)全表更新或者删除;

触发表锁的命令:(1)ALTER TABLE;(2)DROP TABLE 或者 TRUNCATE TABLE;(3)LOCK TABLES;(4)全表扫描或者大范围扫描;(5)加全局锁;

风险:(1)性能下降;(2)多表操作,如果没有按照一定顺序操作表,可能会导致死锁;

三、行级锁:

粒度上区分:共享锁和排他锁

主要由INNODB存储引擎提供,包含共享锁(读锁,也是S锁)和排他锁(写锁,也是X锁)。实际使用中,还有一种间隙锁,会锁定行锁前后的间隙,防止数据插入。

使用场景:(1)高并发读写操作;(2)单行操作;(3)短期锁;(4)实现并发控制;(5)复杂的事务处理;

触发表锁的命令:
(1)select ... for update:添加一个排他锁;
(2)select ... LOCK IN SHARE MODE:添加一个共享锁;
(3)INSERT、UPDATE、DELETE:添加排他锁;

风险:(1)死锁;(2)锁升级:事务锁定行过多,可能导致上升到表锁;(3)锁等待;(4)资源消耗;(5)难调试和排查;(6)事务隔离级别;

模式上区分:乐观锁和悲观锁

乐观锁:认为冲突概率低,操作数据时,不会锁定数据,只有在提交修改时,才检查。如果数据已被修改,则回滚,否则提交。

mysql并没有内置乐观锁机制,需要在代码中实现,常见的实现方式是,使用时间戳或者版本号字段,记录每一次对数据的修改。

标志SQL:(1)select id,version from .xxx ...;(2)update xxx set ... where ... and version = 旧version; 

乐观锁使用场景:(1)低冲突环境;(2)读多写少场景;(3)短事务操作;(4)分布式系统;(5)互联网应用;

风险:(1)冲突检测:只有提交时才检测,有冲突会导致所有都回滚;(2)依赖于版本管理;

悲观锁:一种并发控制方法。认为冲突概率高,每次读写前都加锁;

使用方式:参考前面提到的共享锁(S锁)和排他锁(X锁);

使用场景:(1)写操作比较多;(2)并发冲突高;(3)业务需要强一致性的场景;

缺点:(1)性能开销;(2)并发降低;(3)死锁;(4)锁超时;

四、意向锁

意向锁是表锁。为了协调行锁和表锁的关系,支持多粒度锁并存(即行锁和表锁)。

意向锁也分共享锁和排他锁。

作用:当事务A有行锁时,mysql自动给该表添加意向锁。当事务B申请整张表的写锁时,只需要判断是否存在意向锁,而不需要判断所有行锁。

意向锁的兼容互斥性:

意向共享锁(IS)意向排他锁(IX)
共享锁(S)兼容互斥
排他锁(X)互斥互斥

五、临键锁

可以理解为一种特殊的间隙锁,临键锁可以解决幻读的问题。

当事务拥有某一行记录的临键锁时,会锁住一段左开右闭的区间。比如后面截图中的3条数据,就生成了4个临键锁,临键锁如下:(1)(-∞,20];(2)(20, 25];(3)(25, 30];(4)(30, +∞];
当更新age=25的记录时,不能增加或者修改age为(25, 30]之间的数。

sql语句说明如图:
创建测试表,并插入相应数据,然后开启事务,并更新年龄为25的记录。

 

没有commit更新的情况下,新开一个窗口,执行插入语句,年龄在25-30之间,结果插入被阻塞,这就是因为临键锁。

六、记录锁

mysql的innodb引擎的一种锁定机制,用于锁定和控制单个行记录的访问。

记录锁作用在索引上,对于没有主键和唯一键的表,innodb会自动添加隐藏的聚簇索引,并在该索引上加锁。

七、间隙锁

where条件是一个范围时,数据库会锁定区间数据,主要是解决幻读问题。

使用场景:(1)防止幻读;(2)范围查询;

缺点:(1)性能影响;(2)死锁;(3)复杂性;(4)锁定范围过大,可能导致不必要的锁定冲突;

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
对于Spring事务和数据库的相关问题,我可以为你提供一些基本的信息。请注意,以下内容仅供参考。 Spring事务是一种用于管理数据库操作的机制,它确保了数据的一致性和完整性。在Spring中,你可以使用声明式事务或编程式事务来管理数据库操作。 声明式事务是通过在方法或类级别上添加事务注解来实现的。常用的事务注解包括`@Transactional`,它可以应用在方法或类上,并提供了一系列属性来配置事务的行为。 编程式事务是通过编写代码来手动管理事务的开始、提交和回滚过程。Spring提供了`TransactionTemplate`类来支持编程式事务管理。 关于数据库,它是一种用于控制并发访问数据库的机制。数据库可以保证数据的一致性和完整性,防止多个事务同时对同一数据进行修改而导致冲突。 常见的数据库包括行级、表级和页级。行级用于数据库中的单个数据行,表级用于定整个表,而页级则用于数据库中的页。 在Spring事务中,默认情况下,使用的是数据库的行级机制。如果需要使用其他级别的或更复杂的模式,你可以在SQL语句中明确指定。 需要注意的是,使用机制可能会导致性能下降和死等问题。因此,在设计和实现数据库操作时,需要合理地选择和使用机制。 希望以上信息对你有所帮助。如果你还有其他问题,请继续提问。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值