数据的锁定分为两种,第一种叫做悲观锁,第二种叫做乐观锁。
1、悲观锁,就是对数据的冲突采取悲观的态度,也就是假设数据肯定会冲突,所以在数据开始读取的时候,就把数据锁定住。【数据锁定:数据将暂时不会得到修改】
2、乐观锁,认为数据一般情况下不会造成冲突,所以在数据进行提交更新的时候,才会正式对数据的冲突与否进行检测,如果发现冲突了,则让用户返回错误的信息。让用户决定如何去做。
理解:
1.乐观锁是一种思想,具体实现是,表中有一个版本字段,第一次读的时候,获取到这个字段。处理完业务逻辑开始更新的时候,需要再次查看该字段的值是否和第一次的一样。如果一样更新,反之拒绝。
之所以叫乐观锁,因为这个模式没有从数据库加锁。
2.悲观锁是读取数据的时候为后面的更新加锁,之后再来的读操作就会等待。这种是数据库锁
乐观锁优点程序实现,不会存在死锁等问题。他的适用场景也相对乐观。阻止不了除了程序之外的数据库操作。
悲观锁是数据库实现,他阻止一切数据库操作。
再来说更新数据丢失,所有的读锁都是为了保持数据一致性。乐观锁如果有人在你之前更新了,你的更新应当是被拒绝的,可以让用户从新操作。悲观锁则是会等待前一个更新完成。这也是区别,具体业务具体分析。
实现:
一、悲观锁
1、排它锁,当事务在操作数据时把这部分数据进行锁定,知道操作完毕后再解锁,其他事务操作才可以操作该部分数据,这将防止其他进程读取或修改表中的数据。
2、实现:大多数情况下依靠数据库的锁机制实现
一般使用 select ... for update 对所选择的数据进行加锁处理,例如 select * from account where name = "Suey" for update,这条sql语句锁定了account 表中所有符合检索条件(name="Suey")的记录。本次事务提交之前(事务提交时会释放事务过程中的锁),外界无法修改这些记录。
二、乐观锁
1.如果有人在你之前更新了,你的更新应当是被拒绝的,可以让用户重新操作。
2.实现:大多数基于数据版本(Version)记录机制实现
具体可通过给表加一个版本号或时间戳字段实现,当读取数据时,将version字段的值一同读出,数据每更新一次,对此version值加一。当我们提交更新的时候,判断当前版本信息与第一次取出来的版本值大小,如果数据库表当前版本号与第一次取出来的version值相等,则予以更新,否则认为是过期数据,拒绝更新,让用户重新操作。