где создаются 2 и более сущности?
Например, есть курсы и у курсов есть вопросы. На странице админки заполняются поля курсов и пункт вопросы. После фронт кидает только один запрос, а у меня на этот запрос открывается транзакция и под ней создаю вопросы и курсы, тем самым гарантируя бизнесу что в бд будет и курсы и вопросы
Вопросы это отдельные сущности?
Если при внесении изменений в несколько сущностей БД в процессе возникает неконсистентное состояние, то нужна транзакция. В примере с курсами и вопросами, если действительно курсы без вопросов не имеют смысла, то транзакция нужна. В классическом примере по переводу денег между юзерами (у одного уменьшаем баланс, у другого увеличиваем) нужна. А если, к примеру, создаёт профиль юзера и сохраняем его аватарку в отдельную таблицу, то, т.к. профиль пользователя и без аватарки норм, лучше без транзакции. Дальше зависит от самой СУБД. Если не SQLite, то лучше воздержаться от создания кучи транзакций в цикле. Если из таблицы куда мы хотим записывать через транзакцию происходит интенсивное чтение, то чтение деградирует и придётся настраивать реплику на чтение.
Создавать в одной транзакции одну и более сущностей это нормально, поскольку тогда не надо запариваться с синхронизацией. Ради UI такое объединение нормально. Если сущности объединяются не ради UI в одну транзакцию, а из-за инвариантов, то возможно, стоит посмотреть в сторону Aggregate Root (хотя бы идею понять), который как раз определяет границы атомарной работы с сущностями. Если конкретно по транзакциям, то, например, в Postgres, важно чтобы они были короткими по времени. Из-за долгих транзакций табличный файл быстрее растёт в размерах. Еще минус долгих транзакций в том, что коннекты к бд не бесконечные, и надо как можно быстрее вернуть коннект в пул, чтобы другим хватило
Эмм... ты смешал бизнес-транзакцию и транзакцию-базыДанных. Бизнес транзакция может быть сколь угодно долгой, например человек пол дня заполняет курс, при этом транзакция-БД еще не запущена, но бизнес-транзакция уже начата. Человек заполнил курс, отправляет тебе на сервак, что бы добавить название курса + вопросы к нему + еще что то. Вот тогда ты уже и запускаешь транзакцию-БД, скопом внося данные. При этом, бизнес-транзакция еще не завершена, и ждет пока отработает транзакция-БД. Если все удачно, то бизнес-транзакция завершается. Если там в БД есть дубль, в виде курса с таким же названием, то идет откат транзакции-БД, затем бизнес-транзакция делает откат в то место, где ты должен поменять названия, при этом все остальные части сохранены. По факту, если ты работаешь обычными реляционными БД, они уже автоматом все операции оборачивают в транзакции. Это по отношению к транзакции-БД, не путай с бизнес-транзакцией.
Как обеспечить ACID в бизнес транзакции?
Термин ACID слабо применим к бизнес-транзакции. Вот запись в БД, она есть, или ее нет. Все, точка. В свою очередь, бизнес-транзакция может иметь значимые для бизнеса события. Даже факт неудачного завершения бизнес-транзакции, может быть значимым событием, и мы должны сделать об этом запись в БД. НО! Если тебя правильно понял. То давай пример. Есть долгая операция оформления заказа с итоговым снятием денег со счета. Бизнес-транзакция может длится до месяца и более к примеру, при очень долгих подрядах, или специфичных товаров. В таких случаях используют промежуточное резервирование денег на счету. Вот тут будет ACID, мы в определенный момент бизнес-транзакции резервируем деньги, удостоверяемся что данный резерв в БД теперь, и идем дальше делать свою бизнес-транзакцию. Может быть так, что спустя месяц, из за нехватки компонента, бизнес-транзакция отменена по соглашению сторон. Мы отвязываем резерв денег, еще что то делаем + вносим данные о причинах неудачного завершения бизнес-транзакции. В общем. Термин ACID не применим в вопросе бизнес-транзакции. Зачастую, если есть требования бизнеса, то даже неудачно завершенная бизнес-транзакция, уже становиться завершенной транзакцией, только с неудачным результатом, который записан в БД.
Обсуждают сегодня