0

皆さん、

私はレールのアクティブレコードでのトランザクションにかなり慣れていませんが、次のようなコードを持っています:

transaction do
  specimen = Specimen.find_by_doc_id(25)
  specimen.state = "checking"
  specimen.save
  result = Inventory.do_check(specimen)
  if result
    specimen.state="PASS"
  else
    specimen.state="FAIL"
  end
  specimen.save
end

ここでトランザクションを使用する目的は、Inventory.do_check で例外が発生した場合 (これは外部 Web サービスのクライアントであり、一連の HTTP 呼び出しとチェックを実行します)、標本.状態を以前の値にロールバックすることです。 . これが上記のように機能するかどうか知りたいですか?また、私の開発マシンでは、Specimen テーブル全体にロックが設定されているように見えます。そのテーブル/モデルをクエリしようとすると、BUSY 例外が発生します (SQLLite を使用しています)。ロックはそのオブジェクト/レコードにのみ設定する必要があると考えていました。

私はこれに本当に慣れていないので、私の質問は非常に素朴かもしれません.

4

2 に答える 2

1

実装とロックは DB に依存します。私は SQLLite を使用していないので、そのような場合にテーブル全体がロックされても驚かないでしょう。ただし、読み取りは引き続き機能するはずです。おそらく、1 つの接続で 2 つの同時操作が許可されていないためです。他の操作を許可する前に、トランザクションが完了するのを待っています。たとえば、この SO の回答を参照してください: https://stackoverflow.com/a/7154699/2117020

ただし、私の主なポイントは、外部サービスにアクセスしている間はトランザクションを保持するべきではないということです。ただし、実装されていますが、トランザクションを数秒間保持することは望ましくありません。あなたの場合、あなたが望むのは例外から回復することだけです。結果として状態を「FAIL」または「初期」に設定したいだけですか、それとも do_check() で試験片を変更しますか? do_check() が標本を変更しない場合は、次のようにする必要があります。

specimen = Specimen.find_by_doc_id(25)
specimen.state="checking"
specimen.save
# or simply specimen.update_attribute( :state, "checking" )

begin
  specimen.state = Inventory.do_check(specimen) ? "PASS" : "FAIL"
rescue
  specimen.state = "FAIL" # or "initial" or whatever
end
specimen.save
于 2013-02-28T17:17:12.360 に答える
0

ロックは、データベースに大きく依存します。行ロックを使用できます。このようなもの:

specimen = Specimen.find_by_doc_id(25)

success = true

# reloads the record and does a select for update which locks the row until the block exits (its wrapped in a transation)
specimen.with_lock do
  result = Inventory.do_check(specimen)
  if(result)
    specimen.state="PASS"
  else
    specimen.state="FAIL"
  end
  specimen.save!
end

トランザクションで外部サイトをチェックするのは理想的ではありませんが、 with_lock を使用し、データベースが行ロックをサポートしている場合は、この単一の行をロックする必要があります (読み取りがブロックされるため、慎重に使用してください)。

アクティブ レコードのペシミスティック ロックに関するドキュメントをご覧ください: http://ruby-docs.com/docs/ruby_1.9.3-rails_3.2.2/Rails%203.2.2/classes/ActiveRecord/Locking/Pessimistic.html

于 2013-02-28T17:55:36.357 に答える