开发者社区> 问答> 正文

seata的AT模式,如果有多个全局锁@GlobalLock,怎么知道去竞争哪一个

这里有3个方法各自一条线程,5个业务线 3个业务分别是: 1.下单业务(扣减库存->tx1,生成订单->tx2) 2. 采购业务(采购了商品补仓->tx3) 3. 修改状态业务(修改用户状态->tx4,修改余额状体 ->tx5)


@GlobalTransactional
public void doOrder(){ 
      1)扣减库存 
      2)生成订单
 }

@GlobalLock 
public void doAdditional(){ 
     3)增加库存 
}

@GlobalTransactional 
public void doStatus(){
    4)修改用户状态 
    5)修改余额状体 
}

@GlobalLock应该是抢全局锁的吧.@GlobalLock它怎么知道要去竞争的是doOrder()方法中的全局锁?而不是doStatus()方法中的全局锁呢?如果我理解的有误,能给出解释吗?

如果说全局锁,整个系统中只有1个,那个执行doOrder()时要竞争全局锁合情合理,因为要tx1和tx3有可能操作同一条数据, 如果说执行doStatus()时,也同样要竞争全局锁吧?这就不合理,我不牵涉到同条数据的竞争..就因为加了@GlobalLock,其它所有分布式事务都要参与抢锁,不太合理了,

如果按照全局一个锁, doOrder(),doStatus()都要去抢吧,5个业务都要去抢,效率太低了吧,如果业务更多,效率更低吧?

能给出答案吗? 全局锁时多个吗?使用@GlobalTransactional 就会创建一个全局锁吗?,如果是@GlobalLock 它怎么知道去抢那个全局锁?

展开
收起
游客2r4xrnjrvgmoa 2021-05-12 00:59:56 1698 0
1 条回答
写回答
取消 提交回答
  • 你的逻辑和理解是错误的。
    就拿:1)扣减库存 2)生成订单 ;这个全局事务进行举例,该全局事务涉及了2个分支事务,涉及库存表 、订单表,那么该全局事务就会生成2个全局锁,2个全局锁的id(lockKeys)是由修改前后库存表、订单表的表中数据id加工而来。

    另一个全局事务:4)修改用户状态 5)修改余额状体;如果涉及了2张表那么也会生成2个全局锁,但是这2个全局锁和上面库存表、订单表是没有关系的。

    而@GlobalLock 修饰的3)增加库存 这个方法,这个是操作的库存表,那么就和第一个全局事务扣减库存操作的是同一张表,这时候@GlobalLock修改的增加库存这个方法,在commit之前就会去TC那里查询是否有全局事务持有了该库存表的全局锁,有的话就会重试一定的次数,次数尽了还被持有锁则自己就会进行回滚。和另一个全局事务【4)修改用户状态 5)修改余额状体】是没有关系的。

    2024-02-06 17:28:45
    赞同 展开评论 打赏
问答排行榜
最热
最新

相关电子书

更多
《Seata 1.3 新特性以及如何参与社区》 立即下载
事务、全局索引、透明分布式 立即下载
低代码开发师(初级)实战教程 立即下载