数据库MySQL的update本身具有原子性,在修改时,需要持有这行记录的排它锁,没有拿到锁的提交需要阻塞等待。
这样,通过MySQL的update语句,增加where条件,就可以实现有序扣费。
如果使用查询,扣减,再更新值到数据库,是不能实现线程安全的。必须把查询及扣费的计算放到update语句。
像UPDATE table SET x = x - 1 WHERE id = 10 AND x > 0
语句,如果费用不足,会返回0,业务上如果update失败,说明费用不足了。
另外,还需要注意MySQL的事务。增加了事务,update不一定还满足线程安全。可以设置事务隔离级别为SERIALIZABLE
满足线程安全,但是并发性能会有所降低。