withTransaction runs an IO action inside a SQLite transaction: it begins the transaction, commits on success, and rolls back when the action throws an exception. Rollback leaves the database unchanged. section 16.3.3
Adding an entry safely
addEntry dbConn entry = try $ withTransaction dbConn $ do execute dbConn "INSERT INTO entries (id, text, checked, rank) VALUES (?,?,?,?)" entry newIdx <- lastInsertRowId dbConn return $ fromIntegral newIdx The surrounding try returns an SQLError instead of hiding a failed insert, while the transaction prevents a partial database change. section 16.3.3
