YiiFramework Yii2 транзакции

fixxxer

К.О.
Партнер клуба
с транзакциями все-равно надо работать в специальном классе, а не в самой модели
Не совсем согласен.

Если транзакция затрагивает только саму модель в терминах AR, то есть, те самые before/afterSave(), или просто несколько sql-запросов в save(), внешний класс совершенно неуместен.
 

MiksIr

miksir@home:~$
Не совсем согласен.

Если транзакция затрагивает только саму модель в терминах AR, то есть, те самые before/afterSave(), или просто несколько sql-запросов в save(), внешний класс совершенно неуместен.
Вот мне кажется, что скорее неуместны такие операции сохранения AR модели, которые внутри требуют транзакции.
Если у вас такая необходимость, что одна предметная модель размазана по нескольким таблицам, то просто нужно отказаться от AR в пользу датамапера или делать тот самый внешний класс - это в общем получается unit of work, почему и нет.
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
fixxxer, давай представим ситуацию, когда в рамках одной модели нужна транзакция.
Например, пересчет дерева. Ты станешь писать операции с деревом в самой модели ActiveRecord?
Я - нет. Классы AR, которые мапятся на записи базы, у меня делают только одно: маппинг на записи, и ничего больше - инкапсуляция.
Логика приложения - в сервисный слой / unit of work / domain model / ваша конфессия.

Расчет позиции в дереве при разложении на двумерную модель - это промежуточная логика между бизнесом и медиа.
Можно расширить класс маппинга и прописать в нем интерфейс работы с деревом, но я предпочитаю адаптер. В будущем, когда логика операции изменится и потребует участия нескольких таблиц, или таблица разложится на несколько, из адаптера/декоратора будет легче перейти к композиции или внедрить стратегию. Здесь можно обернуть сохранение в транзакцию.

Такой подход дает мне гибкость и полиморфизм. Когда я добавляю новые поля в таблицу, я просто перегенерирую класс мапинга, переношу валидаторы, и все работает дальше.
Когда я добавляю новые таблицы, я меняю сервисный слой где нужно, а старый код работает со старыми классами мапинга.
Если я сильно меняю структуру базы, старый класс маппинга может превратиться в декоратор.
У меня логика такая. Интересно послушать другие варианты.
 
Последнее редактирование:

Vano

Новичок
Вот мне кажется, что скорее неуместны такие операции сохранения AR модели, которые внутри требуют транзакции.
Если у вас такая необходимость, что одна предметная модель размазана по нескольким таблицам, то просто нужно отказаться от AR в пользу датамапера или делать тот самый внешний класс - это в общем получается unit of work, почему и нет.
А я думаю не стоит привязывать модель только к АР классу или к одной таблице. Даже тот самый внешний класс, о котором вы говорите и будет моделью.
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
Vano, модель в MVC - это не конкретный класс, это множество классов, в которых реализовано получение, сохранение и изменение данных, т.е. вся бизнес-логика.
В документации Yii неявно подразумевается, что класс модели - это класс, который относится к модели. Кроме классов-наследников CModel в приложении обычно есть классы собственно приложения.
просто дока по yii - не букварь по ооп
 
Последнее редактирование:

Vano

Новичок
Но Григорий прав. Обьект АР должен давать доступ только к одной таблице (исходя из всеми принятого описания). А вот модель, в моем понимании(хотя может не смогу обьяснить), это законченый самодостаточный абстрактный(потому что человеком придуман) объект, который может охватывать к примеру множество таблиц.
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
Vano, объект AR должен давать доступ к одной записи в таблице. API yii расширило концепцию AR и дает интерфейс для получения коллекции объектов AR, каждый из которых представляет запись
 

MiksIr

miksir@home:~$
Модель - это данные + логика работы с этими данными. Но никак не классы сохранения этих данных. Эдак окажется, что в датамапере мапер - это модель.
 

MiksIr

miksir@home:~$
Но Григорий прав. Обьект АР должен давать доступ только к одной таблице (исходя из всеми принятого описания). А вот модель, в моем понимании(хотя может не смогу обьяснить), это законченый самодостаточный абстрактный(потому что человеком придуман) объект, который может охватывать к примеру множество таблиц.
Объект предметной области не обязательно соответствует одной таблице. Но если это так - то AR не подходит. Если вы используете AR - то объект предметной области мапится в таблицу. А если пытаться и AR оставить и объект "размазать" - это ничего хорошего не получится.
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
Если вы используете AR - то объект предметной области мапится в таблицу.
ну хз, http://design-pattern.ru/patterns/active-record.html
AR - это дословно "логика доступа к данным", а не логика предметной области.

И AR оставить, и объект "размазать" получается вполне неплохо в приложении с большим объемом логики и количеством разработчиков >4.
Таков мой опыт доработки нескольких приложений среднего масштаба, написанных с разным подходом, и алгоритм, оптимальный по затратам рабочего времени по своему опыту.

К идее оставить AR-класс без изменений я пришел после очередного перечитывания банды 4х про абстрактные фабрики для разных графических сред. Для года работы и значительных изменений приложения такой подход удобен. Для коня в вакууме - вероятно, нет.

Мне интересны примеры вашего практического опыта построения архитектуры приложений на yii и практические результаты тех или иных архитектурных решений. Если они есть.
 
Последнее редактирование:

Vano

Новичок
В общем, тут спор из-за того что друг друга не допоняли.

Ну вот к примеру у меня. Есть классы которые расширяют АР - Helpdesk, и HelpdeskAnswers. В них описание таблицы(поведение
(назначить дату создания), названия атрибутов, названия статусов и так, как таблицы связаны по внешнему ключу есть метод возвращающий записи связанной таблицы).
Думаю это назвать АР объектом.(хотя это уже модель, потому-что в Уии АР разширяет модель).

И есть модели для модуля вопросов пользователя.
И вот здесь одна модель использует те два "АР объекта", тут я использую АфтерСейв, транзакции, сценарии, правила(rules). Думаю на Уии это подходящий вариант. В описание MVC вкладываюсь(если не учитывать то, что АР и есть уже модель).
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
Vano, любая работа с базой данных, как и с любыми внешними хранилищами - это модель :)
 

fixxxer

К.О.
Партнер клуба
grigori, я специально уточнил - в рамках ActiveRecord (всем понятно, что это не паттерн, а хрень ;).

Вот простой пример того, где хочется транзакцию для beforeSave+save. Есть некоторое поле с автогенерируемым текстом, хранится в той же таблице. Работает так - берется некоторое нормализованное представление от другого поля (скажем, заголовок статьи, из которого делается токен для ЧПУ URL); если такие в базе в рамках такого же category_id уже есть, то подписываем суффикс 2, 3 итд.
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
fixxxer, что тут еще сказать :)
да, тут любое решение создает проблему

наверное, я бы действовал по обстоятельствам в зависимости от того, что важнее: обработка ошибки при коммите или соблюдение инкапсуляции
 
Последнее редактирование:

fixxxer

К.О.
Партнер клуба
С правильно реализованными на уровне фреймворка вложенными транзакциями и поддержкой оных в before+do+after проблемы как раз не будет.

В laravel-е я извернулся конструкцией вида internalSave() { DB::transaction({ parent::internalSave() }) }, но это, конечно, жесть =)
 

Winner

Новичок
Забавно читать как фреймворки имеют "архитекторов" всеми извращенными способами. :D
Обожаю фреймворки :D
 

AmdY

Пью пиво
Команда форума
Winner, ну, лучше чтобы тебя немного поимели, чем строить свой бордель и работать в нём фулл тайм.
 

Redjik

Джедай-мастер
AmdY, да ладно тебе, он же пишет самый быстрый интернет магазин... видимо на ассемблере
 
Сверху