2010-01-19 2 views
17

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

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

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

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

Хорошо до сих пор, но Srini Penchikala на InfoQ article состояниях:

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

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

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

+0

Я добавил тэг java, так как он рассматривает все виды DI + ORM (не только в java, но это ваш контекст) – Bozho

ответ

8

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

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

+0

Спасибо за ваш ответ. Так, например, если вы хотите сохранить объект, вы вызываете service.save (entity). Моя цель - сохранить объекты, вызвав entity.save(), как описано Craig Wells здесь: http://groups.google.ca/group/EtoE/browse_thread/thread/cac1eafe15f06f5b/ – semberal

+0

Вы правы, мой код делает например, service.save (entity). Мне не нужен подход «entity.save()», я прочитаю статью, с которой вы связались, и отредактируйте мой ответ с объяснением.) –

+1

И в случае service.save (entity) какая логика остается в объект домена? – Bozho

5

См. this extremely useful blog-post. В нем объясняется, как добиться плавного DDD, не теряя возможности Spring и JPA. Он сосредоточен вокруг аннотации @Configurable.

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

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

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

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

+0

Привет, спасибо за ответ. Я уже прочитал эту статью. Первые два предложенных решения неприемлемы. Мне тоже не нравится решение с перехватчиками спящего режима, потому что (насколько я понял) он решает только инъекцию фасолей, созданных спящим режимом. Решение AspectJ кажется довольно хорошим. Мне нужно было только выяснить, как использовать транзакции в @Configurable классах. Но он не отвечает на вопрос, должна ли моя модель домена быть транзакционной или нет. Если нет, то где должны быть транзакции. – semberal

+0

Я добавил абзац, касающийся транзакций. – Bozho

+0

Я знаю, но в статье, опубликованной вами, упоминается, что @Configurable классы не работают с @Transactional. – semberal

0

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

Смежные вопросы