问一个数据库乐观锁的问题

通常我们采用引入一个version版本号来作为乐观锁,提交的时候校验这个版本号,那么此时有两种方式

方式一,程序中对版本加一,即判断条件为数据库版本小于当前传入的版本:
update set name = ${name} and version = ${version} where id = ${id} and version < ${version}

方式二,通过数据库进行加一,即判断条件为数据库版本等于当前传入的版本:
update set name = ${name} and version = version + 1 where id = ${id} and version = ${version}

请问下,这两种方式有什么不同吗,因为我看几乎所有的乐观锁都是用第二种方式来实现的

阅读 2.9k
3 个回答

结果是一样的,方法二比较好理解点罢了。

很多情况下,乐观锁并不需要version,比如你要UPDATE的是name这一列,那就可以把name当成version,这样就可以写成:

UPDATE ... SET name = ${newname} WHERE id = ${id} AND name = ${oldname}

我也不知道用方法一该怎么来写呢。

假设用户1和用户2同时获得数据version=1,并提交更新,用户1提交的version=2,用户2提交的version=3。

那么用第一种方法,用户1更新完数据后,用户2的数据会覆盖掉用户1的数据;
而用第二种方法,用户2更新时,发现version已经是2了,那么他就提交失败了,或者重新获取数据。

个人觉得可以从并发角度来理解,如:原version值为1,同时发生了两个更新请求,version都是2,语句一的后果可能是两次更新后,version是2,语句二的后果应该是两次更新后,version是3。

语句一和语句二的另一个差别在于,语句一表示只要当前version比原version大即可更新,而语句二表示必须基于某一指定version才能更新,如:原version为1,语句一表示当前version无论是2还是5都可以更新,而语句二表示只有传入更新条件中旧版本号为1才能更新。不过这点的好处我倒是没看出来。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题