文章目录

  • 乐观锁、悲观锁
  • 乐观锁的优点
  • Redis中的锁
  • 总结


乐观锁、悲观锁

锁有什么用?

在数据库执行数据操作时,为了保证数据的一致性,即:A用户更新数据时,B用户不能更新!

在没有锁的情况下:

如果A、B都去针对相同的数据做更新操作。
数据库中的数据为最后提交的数据。

锁是什么?

在数据库的设计上,分为两种:悲观锁乐观锁

  • 悲观锁:基于数据库的操作实现。
    在数据库数据操作时,如果A用户查询到指定的数据,并增加for update属性后

select * from user where id = 1 for update;

此时的数据库将该数据加锁,B用户需要修改该数据,只能在A用户事务提交或连接断开后,才能执行数据操作。

  • 乐观锁:基于算法的实现。
    比如:在数据库中增加一个锁的处理列。

当A和B请求来操作时,都会拿到锁的处理列,假设此时的数据为1

redis中watch做乐观锁 redis实现乐观锁_数据库

当A进行数据处理操作,此时不仅修改具体的数据信息,还会修改锁处理列中的数据信息,假设此时修改数据为2

redis中watch做乐观锁 redis实现乐观锁_redis中watch做乐观锁_02

此时B处理数据,发现锁的处理列数据变更,与其最初拿到的数据不一致,导致B无法执行数据的更新操作。

redis中watch做乐观锁 redis实现乐观锁_数据_03

乐观锁的优点

悲观锁在执行时,会将其他处理数据库的请求拦截,使其他请求等待。
乐观锁在执行时,不会将数据锁住,让其他数据库请求等待。

Redis中的锁

在Redis中,直接支持使用乐观锁

如何观察Redis使用乐观锁做数据操作处理?

使用两个不同的sqlsession实现数据的操作。

可以采取克隆当前会话的操作,创建不同的sqlsession

redis中watch做乐观锁 redis实现乐观锁_乐观锁_04

以下为测试步骤:

  • 在窗口1(Session 1)中执行如下操作:

创建一条记录数;
开启监听;
开启事务。

redis中watch做乐观锁 redis实现乐观锁_数据库_05

  • 窗口2(Session 2)中执行如下操作:

针对age属性变更其数据信息;

redis中watch做乐观锁 redis实现乐观锁_乐观锁_06


发现在2中,可以变更数据,但1中的数据只是开启了事务,并未做处理。

  • 返回窗口1(Session 1)修改数据,并执行事务的提交

    发现此时事务的提交返回(nil)

总结

由于session 2 已经更新了原始数据,那么表示原始数据上的一个标记更新,这样当Session 1 在进行更新时,就会返回(nil),意味着本次事务提交更新操作失败!