Доменный дизайн и транзакции в среде Spring - PullRequest
19 голосов
/ 19 января 2010

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

Прочитав пару статей в Интернете, прослушав выступление Криса Ричардсона о «Парли» и прочитав DDD-главы «POJO в действии», я думаю, что получил общую картину.

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

Уровень представления обрабатывает HTTP-запросы из браузера пользователя, вызывая модель предметной области прямо или косвенно через фасад, который, как я в предыдущей главе описывается либо POJO, либо EJB.

Пока хорошо, но Срини Пенчикала в статье InfoQ утверждает:

Некоторые разработчики предпочитают управлять транзакциями в классах DAO, что является плохим дизайном. Это приводит к слишком детальному управлению транзакциями, что не дает гибкости управления случаями использования, когда транзакции охватывают несколько объектов домена. Классы обслуживания должны обрабатывать транзакции; таким образом, даже если транзакция охватывает несколько объектов домена, класс обслуживания может управлять транзакцией, поскольку в большинстве случаев класс обслуживания обрабатывает поток управления.

Хорошо, поэтому, если я правильно понимаю, классы репозитория не должны быть транзакционными, уровень обслуживания (который теперь намного тоньше) является транзакционным (как это было в шаблоне сценария транзакции). Но что, если доменные объекты вызываются непосредственно на уровне представления? Означает ли это, что мой объект домена должен иметь транзакционное поведение? И как реализовать это в среде Spring или EJB?

Это кажется мне странным, поэтому я был бы рад, если бы кто-нибудь это прояснил. Спасибо.

Ответы [ 4 ]

10 голосов
/ 19 января 2010

Моя личная цель применения DDD в Spring и Hibernate на данный момент состоит в том, чтобы иметь транзакционный уровень обслуживания без сохранения состояния и получать доступ к объектам домена через него. Поэтому, как я это делаю, модель предметной области вообще не знает о транзакциях, которые полностью обрабатываются сервисами.

Существует пример приложения , которое может оказаться полезным для ознакомления. Похоже, что Эрик Эванс участвовал в его создании.

7 голосов
/ 19 января 2010

См. этот чрезвычайно полезный пост в блоге . В нем объясняется, как добиться плавного DDD, не теряя при этом возможностей Spring и JPA. Он сосредоточен вокруг аннотации @Configurable.

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

Да, это нарушает инкапсуляцию, но не заставляет вас использовать какое-то «волшебство» (aop + java agent) для достижения ваших целей.

Что касается транзакций - есть то, что называется распространением транзакций. Spring поддерживает это с @Transactional(propagation=Propagation.REQUIRED). См. Это, пункт 9.5.7 . Если вы хотите, чтобы ваши транзакции охватывали несколько методов (из нескольких объектов), вы можете соответствующим образом изменить атрибут распространения.

Вы также можете использовать @Transactional в своем слое обслуживания, где это уместно, но это может привести к появлению большого количества классов обслуживания в котельной, если вы хотите использовать простые одношаговые операции, такие как «сохранить».

1 голос
/ 25 февраля 2010

Я думаю, что одним из простых способов начать работу с DDD и Spring и иметь хорошие примеры того, как работать с транзакциями, является просмотр одного из примеров приложений, поставляемых с Spring Roo .Ру выпускает код, который следует принципам DDD.Это сильно зависит от AspectJ.Я подозреваю, что это было реализовано на основе идей, выдвинутых (еще в 2006 году) одним из тяжеловесов SpringSource, Рамнивасом Ладдадом, в этом выступлении .

0 голосов
/ 12 мая 2018

К сожалению, я не ознакомился со Spring, но я дам отзыв о вашем понимании DDD. Прочитав ваше описание транзакции, очевидно, что вы не поняли DDD, особенно концепции Aggregate, Aggregate Root и Repository.

В DDD транзакция не может охватывать агрегаты, поэтому один агрегат всегда будет иметь одну транзакцию.

...