MaybeT и транзакции в runDb

Для моего предыдущего вопроса о цепочечных сбоях Майкл Снойман предложил мне использовать 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 будет откат на Nothing внутри MaybeT? Нужно ли использовать какую-то другую монаду, чтобы это работало?

Цените ваши мысли о том, как лучше всего откатиться на неудачу.

Обновление: это то, что я закончил делать по предложению Майкла.

mauth <- runDb $ do
          ma <- runMaybeT $ do
                   valid <- ... 
          case ma of
            Just _ -> return ma
            Nothing -> liftIO $ throwIO MyException

Теперь мне нужно выяснить, как правильно перехватить это исключение и вернуть правильное сообщение об ошибке.

Спасибо!

1 ответ

Решение

Возврате Nothing это не то же самое, что неудача. Вам нужно будет выдать исключение времени выполнения (через что-то вроде throwIO) для упорных трактовать это как ситуацию отката.

Другие вопросы по тегам