Двухфазный коммит в MongoDB
Внимательно прочитавонлайновую документацию , у меня все еще остается много вопросов о двухфазном коммите в MongoDB.
В разделе восстановление после сценариев сбоев, почему существует только два класса сбоев? По моему мнению, неудача может произойти на любом из этих этапов, поэтому здесь должно быть гораздо больше, чем два класса. Например, что делать, если (в разделе применить транзакцию к обеим учетным записям) после обновления учетной записи a сервер базы данных потерпел неудачу. Тот значит, счет а потерял какие-то деньги без того, чтобы что-то произошло на счете Б. И у нас была бы несогласованная транзакция?
3 ответов:
В моем мышлении неудача может произойти на любом из этих этапов, поэтому здесь должно быть намного больше, чем два класса.Здесь важно помнить, что документация не является окончательным руководством по двухфазным коммитам, на самом деле двухфазные коммиты технически невозможны в MongoDB, и я настоятельно рекомендую вам получить ACID tech, если вы хотите их выполнить.
Вы должны помнить, что есть определенные сценарии неудач, которые вы не можете противостоять из-за этого не находясь внутри самого сервера. Вместо этого все существование двухфазных коммитов - это только клиентская сторона, как таковая, она довольно хрупка по сравнению с, скажем, мониторингом TTL.
После обновления учетной записи a произошел сбой сервера базы данных. Это означает, что счет а потерял часть денег, но ничего не произошло на счете В. И у нас была бы непоследовательная транзакция?
В поддержку ответа Филиппса первоначальная транзакция между счетами A и B все еще будет отложена в этом случае, она будет будет перемещен в finished / completed только после обновления учетной записи B.
Это означает, что транзакция не может быть помечена как завершенная, пока она не будет завершена.Вместо использования MongoDB для сценария, для которого он на самом деле не предназначен, я бы рекомендовал использовать что-то, что предназначено для вашего сценария.
Когда приложение или база данных внезапно аварийно завершает работу между применением транзакции к A и применением транзакции к B, в глобальной коллекции транзакций по-прежнему будет присутствовать транзакция с
state:"pending". Ваш сценарий восстановления, который вы запускаете после сбоя, должен заметить это, проверить два счета и увидеть, что есть ожидающая транзакция в одном, но не в другом счете. Теперь он знает все, что ему нужно знать, чтобы либо откатить транзакцию, либо попытаться завершить оно.Да, написать сценарий восстановления, который является таким умным, непросто. Но транзакции в системе баз данных, не предназначенной для них, всегда трудны. Иногда вы можете обойти требование транзакций в MongoDB, разработав свои документы таким образом, что поля, которые должны быть обновлены вместе, всегда находятся в одном документе, но не всегда есть разумный способ сделать это. Когда ваш прецедент абсолютно нуждается в транзакциях, защитите свое здравомыслие и используйте реляционную базу данных.
Онлайновый документ может быть несовершенным. на самом деле вам действительно нужно выполнить операции отката на A и B
Comments