如何实现下单扣库存操作
先扣减库存
扣减成功后,创建订单;
假如创建订单异常,需要归还库存
先判断库存,然后创建订单
先判断库存,如果库存足够,则创建订单,然后扣减库存,如果库存扣减失败,回滚创建;
如何实现银行转账
银行转账业务涉及两大问题:
- 如何在DDD中实现转账逻辑
- 如何保证ACID
先来看第一个问题:如何使用DDD实现转账,一个最好的实现方式是将转账操作放到领域服务里,如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
public class AccountDomainService { final AccountRepository accountRepository; public void transfer(String fromAccountId, String toAccountId, Long money) { Account fromAccount = accountRepository.load(fromAccountId); Account toAccount = accountRepository.load(toAccountId); fromAccount.transferOut(money); toAccount.transferIn(money); accountRepository.save(fromAccount); accountRepository.save(toAccount); // generate a transfer transaction record } } |
当看完上面的实现后,产生了另外一个问题,就是如何保证数据的一致性,当两个人同时给A转账,可能会发生,两个事务同时读到100元,都给该账户+10元,
最后保存到数据库里 110元,而实际应该是 120元。
目前能想到的最佳方案是,每张表都加一个version
字段
- 这样SQL层面也不需要考虑业务逻辑,导致我们需要使用
money=money-x
的SQL语句来保证不会超支的业务; 并且通过在;version
字段上设置索引,也可以使用行锁来提升系统并发