この疑似コード ブロックでは:
atomically $ do
if valueInLocalStorage key
then readValueFromLocalStorage key
else do
value <- unsafeIOToSTM $ fetchValueFromDatabase key
writeValueToLocalStorage key value
安全に使用できunsafeIOToSTM
ますか? ドキュメントは言う:
STM 実装はトランザクションを複数回実行することが多いため、IO に副作用がある場合は、これに備える必要があります。
基本的に、トランザクションが失敗した場合、他のスレッドが原因で
wroteValueToLocalStorage
あり、トランザクションが再試行されると、データベースから再度フェッチする代わりに、保存された値が返されます。STM 実装は、無効であることがわかっているトランザクションを中止し、再起動する必要があります。これは unsafeIOToSTM の途中で発生する可能性があるため、解放が必要なリソースを取得しないようにしてください (トランザクションを中止する場合、例外ハンドラーは無視されます)。これには、たとえばハンドルを使用した IO の実行が含まれます。これを間違えると、ランダムなデッドロックが発生する可能性があります。
これが一番気になります。論理的に
fetchValueFromDatabase
は、新しい接続が開かれない場合 (つまり、既存の接続が使用されている場合) は、すべて問題ないはずです。私が見逃している他の落とし穴はありますか?トランザクションは、IO の実行時にメモリの一貫性のないビューを認識した可能性があります。プログラム全体で真であると期待される不変条件は、トランザクションの実装方法により、トランザクション内では真ではない場合があります。通常、これはプログラマーには表示されませんが、unsafeIOToSTM を使用すると公開される可能性があります。
key
単一の値であり、破る不変条件はありません。