コンピュテーション式で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 }


状態系のコンピュテーション式を導入するとコンピュテーション式の外から呼ぶのが手間なので、副作用のある関数とない関数を分離しやすくなるかもですねぇ。