거래가 뭐예요?언제 써요?사용법

9176 단어 RubyRailsTransaction

거래 소개

トランザクションとは複数の処理をまとめて1つの大きな処理として扱う機能です。여러 자원에 대한 변경 사항을 통일적으로 처리할 때 처리 중의 하나가 예외가 발생할 때 여러 처리를 되돌릴 수 있다.
거래를 정확하게 사용하면 된다致命的なデータの不整合性防ぐ.

왜 거래가 필요합니까?


거래가 왜 필요한지 이해하기 위해 자주 사용되는 예인 은행 계좌의 송금으로 설명하고 싶습니다.
잔액이 10000엔인 A씨, 그리고 잔액이 20000엔인 B씨를 가정해 보세요.
A 씨는 B 씨에게 5000엔을 송금하려고 합니다.
그때는 다음과 같은 두 가지 처리로 구성되어 있다.1、 Aさんの口座から5000円差し引き、残高が10000円 - 5000円 = 5000円になる 2、Bさんの口座に5000円プラスされ、残高が20000円 + 5000円 = 25000円になる
하지만 이 두 가지 처리는 송금의 한 가지 처리로 고려해야겠죠.
왜냐면 두 가지 처리를 분리해서 고려하면 A씨가 5천엔을 송금한 뒤 곧바로 시스템 고장이 발생했을 때 다음과 같은 이유가 됐기 때문이다.1、 Aさんの口座から5000円差し引き、残高が10000円 - 5000円 = 5000円になる   ----------------------システムトラブル発生---------------------- 2、Bさんの口座にお金お金が振り込まれない
이런 사태를 피하기 위해 두 처리를 하나의 송금으로 처리함으로써 A씨가 5천엔을 송금한 뒤 시스템 장애가 발생해도 하나의 송금으로 처리가 실패해 처음부터 송금이 없었다면 5천엔의 소실을 막을 수 있었다.
이런 상황에서 여러 개의 처리를 하나의 큰 처리로 처리해야 한다.

사용법


transaction 방법의 기본 문법


transaction 방법의 기본적인 쓰기 방법은 다음과 같다.아주 간단한 구조예요.

ActiveRecord::Base.transaction do
  # 例外が発生するかもしれない処理
end
  # 例外が発生しなかった場合の処理
rescue => e
  # 例外が発生した場合の処理

사용법


여기에는 Payment(입금), PaymentHistory(입금 이력)의 모델이 존재한다고 가정한다.
입금이 있으면 입금 이력 작성 처리를 보겠습니다.
다음은 transation 블록을 사용하지 않고 이루어진 처리입니다.
def create
  payment = Payment.new(
    amount: 1000
  )
  payment.save!

  payment_history = PaymentHistory.new(
    amount: 1000,
    payment_day: Time.zone.now.strftime('%Y/%m/%d/%H時%M分%S秒')
  )
  payment_history.save!
end
이렇게 집행되는 경우 PaymentHistory 제작 시 어떤 예외가 발생하면 송금이 이뤄지지만 입금 이력이 없는 데이터의 불일치성이 발생한다.
실제 예외가 발생했을 때의 데이터를 봅시다.
mysql > SELECT * FROM payments;
     +-----+--------+
     | id  | amount | 
     +-----+--------+
     | 1   | 1000   |
     +-----+--------+
mysql > SELECT * FROM payment_histories;
    Empty set (0.00 sec)
위에서 말한 바와 같이 Payment의 기록이 만들어졌고 PaymentHistory의 기록은 존재하지 않는다.
상기 데이터의 어댑터를 피하기 위해transsaction 블록을 사용할 때全処理が成功 또는処理が失敗しキャンセル 처리 결과가 제한될 수 있습니다.
다음은transation 블록을 사용하여 실시한 처리입니다.
def create
  ActiveRecord::Base.transaction do
    payment = Payment.new(
      amount: 1000
    )
    payment.save! # まだコミットされない

    payment_history = PaymentHistory.new(
      amount: 1000,
      payment_day: Time.zone.now.strftime('%Y/%m/%d/%H時%M分%S秒')
    )
    payment_history.save! # まだコミットされない
  end
   # transactionブロックを正常に抜けるとコミットされる
end
transation 블록을 사용하는 코드에 대해transation 블록 내의 처리가 예외 없이 완료되면 제출하고 등록에 성공합니다.
다음은 당시의 데이터다.
mysql > SELECT * FROM payments;
     +-----+--------+
     | id  | amount | 
     +-----+--------+
     | 1   | 1000   |
     +-----+--------+
mysql > SELECT * FROM payment_histories;
     +-----+--------+--------------------------+
     | id  | amount |       payment_day        | 
     +-----+--------+--------------------------+
     | 1   | 1000   | "2019/07/15/06時35分10秒" |
     +-----+--------+--------------------------+
다른 한편,transation 블록에 이상이 발생하면 뒤집히고 중도 처리를 취소합니다.
다음은 당시의 데이터다.
mysql > SELECT * FROM payments;
    Empty set (0.00 sec)
mysql > SELECT * FROM payment_histories;
    Empty set (0.00 sec)
불완전한 업데이트도 가능한 필수조건이 있기 때문에 일률적으로 논할 수는 없지만, 이렇게 여러 방법save!을 사용하는 경우transaction 블록을 사용하는 것이 좋다.

총결산


그래서 거래에 대해 설명을 했습니다.
여러 자원에 대한 변경 사항을 통일적으로 처리할 때, 처리에 예외가 있으면 여러 처리를 되돌릴 수 있다.
예상치 못한 오류를 방지할 수 있기 때문에 사용할 수 있는 상황에서 일련의 처리에서 거래를 가져오는 것을 토론합시다.

좋은 웹페이지 즐겨찾기