runDb 中的 MaybeT 和事务
MaybeT and Transactions in runDb
对于我之前关于链接失败的问题,Michael Snoyman 建议我使用 MaybeT
到 运行 它们,这样如果其中任何一个失败,它就会短路到 Nothing
.
我的印象是 runDb
运行 一切都在交易中。那么代码中任何一点的失败都不应该自动回滚事务吗?
mauth <- runDb $ runMaybeT $ do
valid <- MaybeT $ return $ listToMaybe errs
uid <- MaybeT $ insertUnique u
vid <- MaybeT $ getBy $ UniqueField v -- this step fails but previous insert does not roll back
auth <- liftIO $ createAuthToken uid
return auth
当我运行上面的代码时,getBy
失败但用户仍然被插入。我是否误解了 runDb
将在 MaybeT
内的 Nothing
上回滚?我需要使用其他一些 Monad 才能工作吗?
感谢您关于如何最好地回滚失败的想法。
更新:
这就是我最终根据迈克尔的建议所做的。
mauth <- runDb $ do
ma <- runMaybeT $ do
valid <- ...
case ma of
Just _ -> return ma
Nothing -> liftIO $ throwIO MyException
现在我需要弄清楚如何在外部很好地捕获此异常并 return 返回正确的错误消息。
谢谢!
返回Nothing
与失败不是一回事。您需要抛出一个运行时异常(通过 throwIO
之类的东西),以便 Persistent 将其视为回滚情况。
对于我之前关于链接失败的问题,Michael Snoyman 建议我使用 MaybeT
到 运行 它们,这样如果其中任何一个失败,它就会短路到 Nothing
.
我的印象是 runDb
运行 一切都在交易中。那么代码中任何一点的失败都不应该自动回滚事务吗?
mauth <- runDb $ runMaybeT $ do
valid <- MaybeT $ return $ listToMaybe errs
uid <- MaybeT $ insertUnique u
vid <- MaybeT $ getBy $ UniqueField v -- this step fails but previous insert does not roll back
auth <- liftIO $ createAuthToken uid
return auth
当我运行上面的代码时,getBy
失败但用户仍然被插入。我是否误解了 runDb
将在 MaybeT
内的 Nothing
上回滚?我需要使用其他一些 Monad 才能工作吗?
感谢您关于如何最好地回滚失败的想法。
更新: 这就是我最终根据迈克尔的建议所做的。
mauth <- runDb $ do
ma <- runMaybeT $ do
valid <- ...
case ma of
Just _ -> return ma
Nothing -> liftIO $ throwIO MyException
现在我需要弄清楚如何在外部很好地捕获此异常并 return 返回正确的错误消息。
谢谢!
返回Nothing
与失败不是一回事。您需要抛出一个运行时异常(通过 throwIO
之类的东西),以便 Persistent 将其视为回滚情况。