世界線航跡蔵

Mad web programmerのYuguiが技術ネタや日々のあれこれをお送りします。

2006年12月29日

途中でコミットできるトランザクション

今まで何回かContinuationネタで使ったことがあるActiveRecord用の「途中でコミットできるトランザクション」をrailsプラグインにしてみた。なんか、意外と自分で実用することが判明してきたので。

ActiveRecord::Base.transactionを拡張して、途中で「ここまで保存」する機能を提供する。

使い方としては、こんな感じ。

Hoge.partially_commitable_transaction{|tx|
  loop
    (なんか処理)
    tx.commit if some_condition?
  end
}

一応、標準のActiveRecord::Base.transactionに対する下方互換性は持っているのだけれども、完全に変わりに使うには何かと問題があるので上書きはしていない。どうしても、という人はお好みで

ActiveRecord::Transactions::ClassMethods.module_eval do
  alias_method :transaction_without_partially_commitability, :transaction
  alias_method :transaction, :partially_commitable_transaction
end

とかしてくださいな。

で、お断りとしては「重要な機能には使わないでください。非常に危険です」

  • Continuationを使ってる
  • Rubyの中でも「落ちやすい」機能
  • Ruby 2.0では無くなるかもしれない機能だし。
  • Continuationによる再突入を想定していないC言語拡張ライブラリなんかがコールスタックに載ってると恐ろしい。
  • ネイティブスレッドとの相性も最悪と思われる。
  • コミット後に別のTransactionを開始しておいて元のものと偽るという荒業
  • そのDBMSのConnectionAdapterがローカル変数になんか情報を保存しているとアウトかも。
  • Rails標準のMysqlコネクタや、postgresql-prではとりあえず動いた。

私ゃ確かに、このテクニックを商売用のコードで使ったけれども、それは「たとえ落ちても、プロセスIDさえ分かっていればrecover可能な、重要性も低い短命なプロセス」だったからで。そういうのとか、せいぜいがMigrationによるデータ投入に使うとか、そういうのがおすすめ。

あとで、subversionリポジトリにも上げとく。

トラックバック

http://yugui.jp/articles/573/ping

現在のところトラックバックはありません

コメント

blog comments powered by Disqus

ご案内

前の記事
次の記事

タグ一覧

過去ログ

  1. 2016年07月
  2. 2016年01月
  3. 2015年09月
  4. 2015年08月
  5. 過去ログ一覧

フィード

フィードとは

その他

Powered by "rhianolethe" the blog system