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?