Awesome
Transaction Monad
Monad for managed transactions. Defines the type DataSource
for getting arbitrary "connections" and Commitable
for
connections that can be either commited or rolled back. Automatically commits all connections after successful execution.
Performs rollback on all connections if any exception is thrown.
The Example.hs
file gives an example dummy datasource implementation and demonstrates Transaction monad usage.
It's as simple as this:
module Example where
import Transactional
data Connection = Connection { query :: String -> Transaction String }
dummyDataSource :: DataSource (Connection)
dummyDataSource = DataSource $ return (Connection dummyQuery, dummyCommitable)
dummyQuery "DELETE FROM USERS" = do
liftIO $ putStrLn $ "querying.."
return "lol"
dummyCommitable = toCommitable (putStrLn "commit") (putStrLn "rollback")
okTransaction :: IO ()
okTransaction = transactionally $ do
conn <- getConnection dummyDataSource
queryResult <- query conn "DELETE FROM USERS"
liftIO $ putStrLn $ "got result: " ++ queryResult
failingTransaction :: IO ()
failingTransaction = transactionally $ do
conn <- getConnection dummyDataSource
query conn "DROP TABLE USERS"
return ()
If you run this in GHCI, you see how connections are commited and rolled back automatically:
*Example> okTransaction
querying..
got result: lol
commit
*Example> failingTransaction
rollback
*** Exception: Example.hs:(10,1)-(12,14): Non-exhaustive patterns in function dummyConnection