Мне не хватало точки открытия базы данных и функции отката, поэтому я использовал runDB myAction
каждый раз, потому что я не понимал, что происходит. Сегодня я сделал некоторые тесты, чтобы попытаться понять, как это делает откат, и один из них был такой:Yesod Постоянное атомное взаимодействие
getTestR :: Handler Text
getTestR = do
runDB $ insert $ Test 0
runDB $ do
forM_ [1..] $ \n -> do
if n < 10
then do
insert $ Test n
return()
else undefined
return "completed"
Я получил undefined
ошибку во время выполнения, как и ожидалось, и только первые runDB
действия получили в базе данных , второй runDB
откинулся назад, и когда я вставил другой реестр, его идентификатор начинался с 9 позиций впереди последнего сохраняемого элемента.
Предположим, что я должен сделать 2 get
сек действия в базе данных, и я их двумя способами, первый я:
getTestR :: FooId -> BooId-> Handler Text
getTestR fooid booid = do
mfoo <- runDB $ get fooid
mboo <- runDB $ get booid
return "completed"
, а затем я пытаюсь:
getTest'R :: FooId -> BooId-> Handler Text
getTest'R fooid booid = do
(mfoo, mboo) <- runDB $ do
mfoo <- get fooid
mboo <- get booid
return (mfoo,mboo)
return "completed"
Какой бы быть фактической общей разницей? Я думаю, что в этом случае консистенция базы данных не является проблемой, но производительность может быть (или будет ленивость Haskell делает их равными, потому что mfoo
и mboo
никогда не используются, чтобы они никогда не запрашивались?). Вероятно, эти вопросы выглядят очень глупо, но я хотел бы быть уверенным, что у меня нет пробелов в моем понимании.
Haskell очень велик, я думаю, что ум программиста, который был открыт для Haskell в течение довольно хорошего времени, никогда не вернется в свое первоначальное состояние. Это похоже на программирование с повышенной мощностью, постоянно совершенствующееся в наших собственных умах и, следовательно, в нашем общем кодировании. – FtheBuilder