コンピュテーション式でADO.NETのトランザクションを表現するアイデア
F#のコンピュテーション式がだんだんとわかってきたので思いついたアイデアをコードに落としてみました。
ADO.NETのトランザクションやコネクションの管理をすっきり書けるようにすることが目標。
ポイントは次のもの。
- トランザクション属性を宣言的に書けるようにする。required { ... } とか requiresNew { ... } みたいな。
- ADO.NETのDbConnectionとかDbTransactionを引数で渡す必要をなくす。かといってスレッドローカルも使わない
こんな感じです。
let insert = required { let! _ = Database.execute "insert person (id, name) values (1, 'hoge1')" let! _ = Database.execute "insert person (id, name) values (2, 'hoge2')" let! _ = Database.execute "insert person (id, name) values (3, 'hoge3')" return () } let delete = required { let! _ = Database.execute "delete from person" return () } let query = required { return! Database.query "select * from person" } let manipulate = requiresNew { do! insert let! result = query do! delete return result }
状態系のコンピュテーション式を導入するとコンピュテーション式の外から呼ぶのが手間なので、副作用のある関数とない関数を分離しやすくなるかもですねぇ。