簡體   English   中英

找出數據庫死鎖

[英]Figure out database deadlock

我正在嘗試編寫springboot代碼以根據DEBIT / CREDIT交易更新錢包余額 我有兩張桌子,也就是。 錢包交易 我正在運行一個測試套件,該套件運行100個並行事務(50借方和50貸方)。 約有50%的交易失敗並出現以下錯誤,並且錢包 表中的錢包余額與交易 表中存儲的交易不匹配

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());
  }

我通過在下面的行中使用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);
}

如果您希望100%的即時一致性,則可以探索功能鎖定概念,將涉及一項交易的錢包保留在功能鎖定表中。 因此,開始時的每筆交易都會檢查錢包中是否有任何功能鎖,如果有,請等到它可以得到功能鎖為止,否則將其插入功能鎖中並繼續進行交易。 在功能鎖表中添加條目應該是原子的,並具有自己的提交。 在交易結束時,刪除鎖定條目。

如果您正在尋找最終的一致性(具有延遲的一致性),則可以考慮使事務更新排隊,並且守護程序可以一個接一個地處理排隊的項目,再次使用功能鎖定概念來避免多個守護程序為同一個錢包處理事務。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM