时间: 2020-04-09 【学无止境】 阅读量:共1675人围观
简介 访问量高的网站都会处理不同的并发问题,一般第一时间都会想到用redis队列等技术,其实也可以使用Mysql数据库的“锁”机制。悲观锁:一般使用 select ...for update 对所选择的数据进行加锁处理。针对于不同的业务场景,应该选用不同的并发控制方式。所以,不要把乐观并发控制和悲观并发控制狭义的理解为DBMS中的概念,更不要把他们和数据中提供的锁机制(行锁、表锁、排他锁、共享锁)混为一谈。其实,在DBMS中,悲观锁正是利用数据库本身提供的锁机制来实现的。
一、悲观锁
1、当事务在操作数据时把这部分数据进行锁定,直到操作完毕后再解锁,其他事务操作才可操作该部分数据。这将防止其他进程读取或修改表中的数据
2、实现:
一般使用 select …for update 对所选择的数据进行加锁处理,例如 SELECT * FROMorder
WHEREorder_no
= ‘123456’ LIMIT 1 FOR UPDATE ,这样就通过开启排他锁的方式实现了悲观锁。此时在 order 表中,order_no 为 123456 的那条数据就被我们锁定了,其它的事务必须等本次事务提交之后才能执行。这样我们可以保证当前的数据不会被其它事务修改。
二、乐观锁
1、如果有人在你之前更新了,你的更新应当是被拒绝的,可以让用户重新操作。
2、实现:
大多数基于数据版本(Version)记录机制实现,具体可通过给表加一个版本号或时间戳字段实现,当读取数据时,将version字段的值一同读出,数据每更新一次,对此version值加一。当我们提交更新的时候,判断当前版本信息与第一次取出来的版本值大小,如果数据库表当前版本号与第一次取出来的version值相等,则予以更新,否则认为是过期数据,拒绝更新,让用户重新操作。
注意
乐观锁如果冲突,会更新失败,要写重试;
悲观锁如果冲突,程序会等待,直到超时,如果程序有问题,用了悲观锁,但是没有事务,或是事务一直没有提交或者回滚,其他的数据写操作就会超时。
所以用悲观锁要注意不能太大事务,导致后面的写操作等不起;且一定要在事务里。