找出数据库死锁

ruyhziif  于 2021-06-20  发布在  Mysql
关注(0)|答案(2)|浏览(333)

我想写一本书 springboot 根据借方/贷方交易更新钱包余额的代码。我有两张table。钱包和交易。我正在运行一个测试套件,它运行100个并行事务(50个借方和50个贷方)。大约50%的交易失败,并出现以下错误,而且wallettable中的钱包余额与transactiontable中存储的交易不匹配
com.mysql.jdbc.exceptions.jdbc4.mysqltransactionrollbackexception:获取锁时发现死锁;尝试重新启动事务
我无法理解以下原因1)为什么死锁2)为什么钱包余额与成功存储的交易数量不匹配。我正在使用mysql innodb作为数据库

@Transactional(isolation = Isolation.SERIALIZABLE)
  public Transaction saveTransaction(String walletId, Txn txn) {
    Optional<Wallet> byId = walletRepo.findById(Integer.parseInt(walletId));
    if (!byId.isPresent()) {
      throw new WalletNotFoundException();
    }
    Wallet wallet = byId.get();
    Transaction transaction = new Transaction();
    transaction.setAmount(txn.getAmount());
    transaction.setType(txn.getType());
    transaction.setWallet(wallet);
    BigDecimal balance = applyTransactionToWallet(txn, wallet.getBalance());
    Transaction save = transactionRepo.save(transaction);
    wallet.setBalance(balance);
    return save;
  }

  public Optional<Wallet> getWallet(String walletId) {
    Optional<Wallet> byId = walletRepo.findById(Integer.parseInt(walletId));
    return byId;
  }

  private BigDecimal applyTransactionToWallet(Txn txn, BigDecimal amount) {
    if (txn.getType() == TransactionType.CREDIT) {
      return amount.add(txn.getAmount());
    }
    return amount.subtract(txn.getAmount());
  }
oxcyiej7

oxcyiej71#

我通过使用 findByIdInWriteMode 而不是 findById 在下面的一行。

Optional<Wallet> byId = walletRepo.findById(Integer.parseInt(walletId));

我把回购改为

@Repository
public interface WalletRepo extends JpaRepository<Wallet, Integer> {
  @Query(value = "FROM Wallet W where W.walletId = :id")
  @Lock(LockModeType.PESSIMISTIC_WRITE)
  Optional<Wallet> findByIdInWriteMode(@Param("id") Integer id);
}
rjjhvcjd

rjjhvcjd2#

如果您想要100%的即时一致性,您可以探索函数锁定概念,将一个事务中涉及的钱包保存在函数锁定表中。因此,每次交易开始时都会检查钱包上是否有功能锁,如果有,就等到它能拿到功能锁,否则就插入功能锁继续交易。在函数锁表中添加条目应该是原子的,并且有自己的提交。在事务结束时,移除锁定项。
如果您正在寻找最终的一致性(具有延迟的一致性),则可以将事务更新排队,并且守护程序可以逐个处理排队的项目,再次使用功能锁定概念来避免多个守护程序处理同一钱包的事务。

相关问题