假设账户A的余额是200,B、C分别给A转账100,A自己又消费了50,期望A的余额是350,那么如何做才能确保数据的一致性?

做法1:在代码里加同步锁(推荐)

synchronized (lock) {
    try {
        // 查账户余额
        UserAccount userAccount = userAccountMapper.selectById(userId);

        // 根据业务场景进行数据处理修改(加100或减50)
        userAccount.setBalance(userAccount.getBalance.add(price));

        // 更新账户余额(update)
        userAccountMapper.update(userAccount);
    } catch (Exception e) {
        log.error("error: " + e.getMessage());
    }
}

做法2:数据库悲观锁FOR UPDATE(不推荐,要考虑可能阻塞数据库的问题)

try {
    // 查账户余额 for update
    // SELECT * FROM USER_ACCOUNT WHERE USER_ID = #{userId} FOR UPDATE
    UserAccount userAccount = userAccountMapper.selectById(userId);

    // 根据业务场景进行数据处理修改(加100或减50)
    userAccount.setBalance(userAccount.getBalance.add(price));

    // 更新账户余额(update)
    userAccountMapper.update(userAccount);
} catch (Exception e) {
    log.error("error: " + e.getMessage());
}

做法3:直接写到sql里(推荐)

UPDATE USER_ACCOUNT SET BALANCE = BALANCE + #{amount} WHERE USER_ID = #{userId}

【数据库】数据库事务原理-CSDN博客

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐