假设账户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}