私はHaskellのSTMライブラリを使用してきましたが、トランザクションを作成する機能と、STMの一般的な「この間違いを取得できない」という性質が本当に気に入っています。
正当な理由で、STMはトランザクション内のIOアクションを許可しません。IOアクションを再試行する方法はありません。(ここに発射ミサイルのリファレンスを挿入してください)。一方、データベーストランザクションには、非常によく似た原子性の保証がいくつかあります。2つを一緒に使用するための受け入れられた方法はありますか?
さまざまな種類のトランザクションを単一のトランザクションの概念にインターリーブすることは「トランザクションブースティング」と呼ばれ、現時点ではHaskellのSTMでそれを行うための優れた方法はありません。ただし、コミット時または再試行時にのみ実行されるアクションを構築する方法があります:http: //hackage.haskell.org/package/stm-io-hooks
さらに、トランザクションの終了と実際のコミットの間に明示的な「トワイライト」を提供するtwilight-stmプロジェクトを試すことができます。私の知る限り、提供されているコードは、パフォーマンスを調整したものというよりもリファレンス実装です。ただし、http://proglang.informatik.uni-freiburg.de/projects/twilight/
それでも、アプリケーションによっては、目的に応じて十分に高速であることが判明する場合があります。
データベースをあまり扱ったことがない人からの一般的な助け:
技術的unsafeIOToSTM
にはを使用できるため、データベースを変更するIOアクションによってアトミック性が保証されている場合は、問題ありません。を使用するブリッジを作成してunsafeIOToSTM
から、そのブリッジをコードで使用して、安全でないものでコードを記述しないようにします。
STM(IO a)を使用することもできますが、これは必ずしも目的に合っているとは限りません。
do r <- atomically $ do ...
r' <- r
また
do r <- join . atomically $ do ...
STMから実行するデータベースクエリを返す場所。これは安全ですが、mVarで行うことは、返すIOアクション内から変更できないため、はるかに制限されます(これは、原子性を維持するため、安全性に関しては良いことです)