美文网首页
select...for update 应用场景

select...for update 应用场景

作者: wbpailxt | 来源:发表于2020-03-04 14:01 被阅读0次

    业务场景:
    通过数据库表来生成全局唯一的订单号。
    实现细节:


    该表的列

    current_value是全局唯一的订单号,select出来即可作为订单号使用。
    step是订单号增长步伐,当此次操作使用了current_value的值作为订单号之后,需要current_value的值以便下个订单使用。更新的方式就是为current_value的值加上step的值。
    会出现的问题:
    假设有两个事务,这个两个事务的操作都是先获取最新的全局唯一订单号,再更新表。

    发生时间编号 事务a 事务b
    1 begin
    2 begin
    3 select * from sequence_info where name = 'order_info'
    4 select * from sequence_info where name = 'order_info'

    这个时候事务a和事务b获取到current_value值是一样的,我们假设是100。

    发生时间编号 事务a 事务b
    5 update sequence_info set current_value = #{currentValue}+#{step} where name = 'order_info'
    6 commit
    7 update sequence_info set current_value = #{currentValue}+#{step} where name = 'order_info'
    8 commit

    到这里,不仅仅有两个订单的订单号是一样的(100,即两个事务取到的current_value的值),而且两次更新按道理说current_value的值应该是增长2个step,但目前只增长了1个step。

    解决办法:
    在select的时候为记录加上X型正经记录锁(X型正经记录锁这个叫法只是我的个人叫法,读者可以理解为排他锁即可)

    发生时间编号 事务a 事务b
    1 begin
    2 begin
    3 select * from sequence_info where name = 'order_info' for update

    这个时候事务b再想select就需要阻塞等待事务a提交了,因为排他锁与排他锁之间不兼容。

    发生时间编号 事务a 事务b
    4 update sequence_info set current_value = #{currentValue}+#{step} where name = 'order_info'
    5 commit
    6 select * from sequence_info where name = 'order_info' for update
    7 update sequence_info set current_value = #{currentValue}+#{step} where name = 'order_info'
    8 commit

    其实还有另外一种类似的解决方案:
    通过update也是可以给记录加上X型正经记录锁的。

    发生时间编号 事务a 事务b
    1 begin
    2 update sequence_info SET current_value = current_value+step WHERE NAME = 'order_info'
    3 select * from sequence_info where name = 'order_info'
    4 commit

    由于update操作为记录添加的是X型正经记录锁,所以只要事务a未提交,别的事务也不能修改记录,甚至是都不能读取。

    发生时间编号 事务a 事务b
    5 begin
    6 update sequence_info SET current_value = current_value+step WHERE NAME = 'order_info'
    7 select * from sequence_info where name = 'order_info'
    8 commit

    相关文章

      网友评论

          本文标题:select...for update 应用场景

          本文链接:https://www.haomeiwen.com/subject/uoamlhtx.html