I have been using Haskell's STM library and I really like the ability to compose transactions and the general "you-can't-get-this-wrong" nature of STM.
For good reason, STM does not allow IO actions within a transaction. There is no way to retry an IO action. (insert Launch missiles reference here). Database transactions on the other hand do have some atomicity guarantees that are very similar. Is there an accepted way to use the two together?
Interleaving different sorts of transactions into a single transaction notion is called "transactional boosting" and there isn't a great way to do it in Haskell's STM at the moment. There is, however, a way to build up actions to be performed only on commit or only on retry: http://hackage.haskell.org/package/stm-io-hooks
Additionally, you could try the twilight-stm project, which provides an an explicit "twilight" between transactions ending and actual commit. As far as I know, the code provided is more of a reference implementation than one tuned for performance, however: http://proglang.informatik.uni-freiburg.de/projects/twilight/
Nonetheless, depending on your application, it may turn out to be plenty-fast for your purposes.
Some general help from someone who hasn't dealt with Databases much:
You can technically use unsafeIOToSTM
, so if you are guaranteed atomicity by the IO action which modifies the database, it should be fine. Just write a bridge that uses unsafeIOToSTM
and then use that bridge in your code to avoid litering your code with unsafe things.
You can also use an STM (IO a) but this doesn't always suit your purpose, like
do r <- atomically $ do ...
r' <- r
or
do r <- join . atomically $ do ...
Where you return the database query to perform from STM. This is safe but much more limited as what you do with mVar's and such cannot be modified from within the IO action you return (which is a good thing with regard to safety as it keeps the atomicity)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With