我现在的处境,我需要 orderService.createOrder()
方法和内部 walletService.reduceBalance()
方法。我想要 orderService.createOrder()
方法读取指定的隔离级别和 walletService.reduceBalance()
具有可重复读取隔离级别。
然而,据我所知,因为 walletService.reduceBalance()
在里面 orderService.createOrder()
,它将读取提交的隔离,尽管有注解(因为它都发生在单个物理事务中)。
public class OrderService {
private WalletService walletService;
@Transactional
public void createOrder(Long userId) {
//some order creation, reads a lot of data
walletService.reduceBalance(userId, orderPrice);
//other operations
}
}
public class WalletService {
private WalletRepository walletRepository;
@Transactional(isolation = Isolation.REPEATABLE_READ)
public void reduceBalance(Long userId, BigDecimal amount) {
Wallet wallet = walletRepository.getById(userId);
wallet.setBalance(wallet.getBalance().substract(amount);
}
}
第一个解决办法是 orderService.createOrder()
可重复读取。但在这种情况下,它会减慢应用程序的速度,因为该方法会读取大量数据,而可重复读取会锁定这些数据。
public class OrderService {
private WalletService walletService;
@Transactional(isolation = Isolation.REPEATABLE_READ)
public void createOrder(Long userId) {
//some order creation, reads a lot of data
walletService.reduceBalance(userId, orderPrice);
//other operations
}
}
public class WalletService {
private WalletRepository walletRepository;
@Transactional(isolation = Isolation.REPEATABLE_READ)
public void reduceBalance(Long userId, BigDecimal amount) {
Wallet wallet = walletRepository.getById(userId);
wallet.setBalance(wallet.getBalance().substract(amount);
}
}
第二个解决办法是 walletService.reduceBalance()
propogation=需要\u new,这将创建具有正确隔离级别的单独物理事务。但在这种情况下,如果 walletService.reduceBalance()
委托交易 orderService.createOrder()
发生异常,订单创建将回滚,减少余额仍将提交。
public class OrderService {
private WalletService walletService;
@Transactional
public void createOrder(Long userId) {
//some order creation, reads a lot of data
walletService.reduceBalance(userId, orderPrice);
//other operations
}
}
public class WalletService {
private WalletRepository walletRepository;
@Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRES_NEW)
public void reduceBalance(Long userId, BigDecimal amount) {
Wallet wallet = walletRepository.getById(userId);
wallet.setBalance(wallet.getBalance().substract(amount);
}
}
你能提出更好的方法来处理这种情况吗?
暂无答案!
目前还没有任何答案,快来回答吧!