Rucksack のパラレルなトランザクション
Rucksack はとても素敵なピュア Common Lisp のパーシステントシステムなんだけど、今の実装はトランザクションが全てシリアライズされて、同時に1トランザクションしか走ることがでない。
Rucksack のメーリングリストですでにパッチを持っている人がいるという話を出ていたけど、そのパッチが全然出てこない。素直に待てばいいかなと思いつつも、ついついなんとかできないかなと思っていじってしまった。
https://github.com/quek/rucksack/tree/parallel2
まず、再帰ロック sb-thread:with-recursive-lock を使っているので SBCL でしか動かない。
コミット時に他のトランザクションがすでに同じオブジェクトをコミットしてないか調べて、コミットされていたら transaction-conflict を投げる。次のように transaction-conflict で rucksack::retry をリスタートすれば、トランザクションがリトライされる。
(handler-bind ((transaction-conflict
(lambda (c)
(invoke-restart 'rucksack::retry))))
(with-transaction ()
...))
Rucksack のコードはきれいだと思った。既にパラレルなトランザクションのためのコードが書かれていて、それを利用することができた。
とりあえず、ちゃんと動いているようだけど、正しいという自信がない。もう少し様子を見てからパッチを投げるとかしたい。