为了账号安全,请及时绑定邮箱和手机立即绑定

检查和更新表中的记录时出现的潜在并发问题

检查和更新表中的记录时出现的潜在并发问题

江户川乱折腾 2022-09-28 15:40:47
情况是这样的,成员必须兑换令牌才能访问(解锁)给定物品。相关的数据库表包括:表 1Table MEMBER_BALANCE: MEMBER_ID, TOKEN_BALANCE表 2Table UNLOCKED_ITEM: MEMBER_ID, DATE_UNLOCKED, ITEM_ID我需要强制执行的检查或约束是当用户尝试解锁项目时,TOKEN_BALANCE必须> 0,并且用户之前未解锁过同一项目。我的直觉倾向是在会员服务中编写一个简单的方法.java:@Transactionalpublic void unlockItem(Member member, Item item){    memberBalanceDAO.decrementBalance(member);    itemDAO.unlockItem(member, item);}我已经通过在表上添加/对的约束来处理第二个要求。uniqueMEMBER_IDITEM_IDUNLOCKED_ITEM我认为,我唯一需要注意的是,用户试图同时解锁许多物品,但未满足要求。例如, 是 1,但用户单击以虚拟方式同时解锁两个项目。TOKEN_BALANCETOKEN_BALANCE以下是我的方法:MemberBalanceDAO.decrementBalance@Transactionalpublic void decrementBalance(Member member) {    MemberBalance memberBalance = this.findMemberBalance(member);    if (memberBalance.getTokens() >= 1) {        memberBalance.setTokens(memberBalance.getTokens() - 1);        this.save(memberBalance);    } else {        throw new SomeCustomRTException("No balance");    }}我不认为这可以保护我免受= 1用例的影响。我担心同时有多个解锁请求。如果余额为 1,我可以同时接到两个调用,两个调用都将余额提交到 0,但随后也收到两个成功的调用,对吧?TOKEN_BALANCEdecrementBalance()itemDAO.unlockItem(...)我应该如何实现这一点?是否应将服务级别方法的事务设置为 ?还是有更清洁/更好的方法来解决这个问题?isolation = Isolation.SERIALIZABLE
查看完整描述

1 回答

?
慕工程0101907

TA贡献1887条经验 获得超5个赞

我宁愿建议您在表中引入列。请参阅文档“乐观锁定”versionmember_balance

正如你所提到的,你不能修改架构;你可以去无版本乐观锁,在这里解释

或者你可能想去悲观的锁定,在这里解释。然后,您可以修改您的方法,在那里获取成员余额,不要使用 。例如decrementBalance()findMemberBalance()

@Transactional

public void decrementBalance(Member member) {

    MemberBalance memberBalance = entityManager.find(

        MemberBalance.class, member.id, LockModeType.PESSIMISTIC_WRITE,             

        Collections.singletonMap( "javax.persistence.lock.timeout", 200 ) //If not supported, the Hibernate dialect ignores this query hint.

    );

    if (memberBalance.getTokens() >= 1) {

        memberBalance.setTokens(memberBalance.getTokens() - 1);

        this.save(memberBalance);

    } else {

        throw new SomeCustomRTException("No balance");

    }

}

铌:它可能无法正常工作;它只是为了给你一些提示。


查看完整回答
反对 回复 2022-09-28
  • 1 回答
  • 0 关注
  • 146 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号