Controle de transação - em qual camada deixar?

Pessoal boa noite,

pensando em um sistema web, na opnião de vocês em qual camada é mais correto deixar o controle de transações de banco de dados.
Na camada de Apresentação (Action) ou camada de Negócios(Business Object)?

Considerando que estou desenvolvendo um sistema web para faculdade com struts e hibernate.

ou seja

eu tenho

  • ACTION - BusinessObject - DAOS

Já fiz tudo só não deleguei ainda para alguém o controle de transações, e aí alguém me da alguma dica?
Quem seria o melhor responsável para tal tarefa? :slight_smile:

Abraços

E porque não deixar para o appserver cuidar das transações via JTA para você ao invés de cuidar de tudo na mão?

Cara mesmo que seja utilizado JTA é necessário dizer aonde inicia e aonde termina uma transação. E nesse caso eu volto ao mesmo ponto, onde, que no fim das contas falando em camadas significa “quem”.

Mas eu já cheguei a uma conclusão para minha situação, o melhor para mim seria deixar esse controle para o Business Object.

Vlw

Em quase todos os casos eu sempre usei CMT, dessa forma o container faz esse controle. Em raros casos precisei usar BMP, mas não lembro de cabeça o motivo.

Mas independente de ser CMT ou BMP o controle da transação sempre deve ficar na camada de negócio, pois é ela que sabe quando há alguma violação de alguma regra. Por exemplo, se você for incluir um usuário você precisa validar se o CPF já existe. Quem irá fazer essa verificação será sua camada de negócio (exemplo, um session-bean), então ele será responsável por saber se deverá ser feito commit ou rollback.

Se você trabalhar com session-beans notará que a transação começa no início da execução do método e termina no final da execução do mesmo. Note que se você chamar 3 métodos de EJB a partir do seu controller você terá aberto e fechado três transações.

Eu não vejo o motivo de você usar o controle de transação em outros locais. A única excessão que eu vejo é quando você está em ambientes não gerenciados o uso de artifícios como o open-session-in-view, porém isso é apenas para casos com JPA ou Hibernate.

[quote=vhmolinar]Cara mesmo que seja utilizado JTA é necessário dizer aonde inicia e aonde termina uma transação. E nesse caso eu volto ao mesmo ponto, onde, que no fim das contas falando em camadas significa “quem”…[/quote]Oi, vhmolinar
Isso tb depende da abordagem e do framework de middleware q vc está utilizando, p/ ex.: se vc adota DDD c/ Spring, na “camada” Repository (ou Repositorio) vc poder usar a @Transactional do Spring (ou seja, invariavelmente fica dentro do domain (ou dominio).), sacou??!

[quote=vhmolinar]Pessoal boa noite,

pensando em um sistema web, na opnião de vocês em qual camada é mais correto deixar o controle de transações de banco de dados.
Na camada de Apresentação (Action) ou camada de Negócios(Business Object)?

Considerando que estou desenvolvendo um sistema web para faculdade com struts e hibernate.

ou seja

eu tenho

  • ACTION - BusinessObject - DAOS

Já fiz tudo só não deleguei ainda para alguém o controle de transações, e aí alguém me da alguma dica?
Quem seria o melhor responsável para tal tarefa? :slight_smile:

Abraços[/quote]

Olá!

Como você disse que a sua transação é de Banco de Dados ela tem que logicamente iniciar e terminar no DAO. Nenhum objeto de business por exemplo, tem que saber que a transação do banco ainda esta aberta.
EX: Abre transação, salva objeto, fecha transação.

Agora, se a sua transação for de business, aí ela tem que iniciar e terminar no seu business ( Duhh! )
EX: Abre transação, remove objeto, salva novo objeto, atualiza objeto dependente, termina transação.

[quote=vhmolinar]Cara mesmo que seja utilizado JTA é necessário dizer aonde inicia e aonde termina uma transação. E nesse caso eu volto ao mesmo ponto, onde, que no fim das contas falando em camadas significa “quem”.

Mas eu já cheguei a uma conclusão para minha situação, o melhor para mim seria deixar esse controle para o Business Object.

Vlw[/quote]Alô, vhmolinar
E aê, poderia dar 1 descrição + detalhada o q é o seu “Business Object” e como vc acabou derfinindo as Transações??! :stuck_out_tongue:

[quote=deniswsrosa]Como você disse que a sua transação é de Banco de Dados ela tem que logicamente iniciar e terminar no DAO. Nenhum objeto de business por exemplo, tem que saber que a transação do banco ainda esta aberta.
EX: Abre transação, salva objeto, fecha transação.

Agora, se a sua transação for de business, aí ela tem que iniciar e terminar no seu business ( Duhh! )
EX: Abre transação, remove objeto, salva novo objeto, atualiza objeto dependente, termina transação.[/quote]

:lol: Mas hein?! Transação na DAO?!?!

Você tem uma transação que começa e termina num momento específico por causa de uma necessidade de negócio. Por isso eu acho que faz mais sentido deixar o controle de transação na camada de negócios. Dependendo do caso, faz mais sentido deixar na camada de aplicação.
De qualquer forma, a camada de infraestrutura tem operações “burras”, ele não deveria saber quais operações de alteração de dados devem ser executadas numa determinada transação.

Alguns frameworks como EJB e Spring te permitem demarcar transações na sua camada de negócios ou aplicação de uma forma transparente. Acho esse o melhor cenário. Já o pessoal do Ruby on Rails não se importa muito em deixar o código de transação no meio do código da camada de negócios…

[quote=Rubem Azenha]…na camada de aplicação.
De qualquer forma, a camada de infraestrutura tem operações “burras”, ele não deveria saber quais operações de alteração de dados devem ser executadas numa determinada transação.

Alguns frameworks como EJB e Spring te permitem demarcar transações na sua camada de negócios ou aplicação de …[/quote]como eu havia falado, né?!! :wink:
@Rubem Azenha,
O vc quer dizer (especificamente) quando fala “camada de aplicação”?

Uma camada que fica entre a camada de visualização e a camada de negócios/domínio.
Ela não contem regras de negócio nem código referente a visualização do sistema. É apenas coordena algumas atividades executada por objetos da camada de negócio.

Não é sempre que precisamos dessa camada, uma grande vantagem dela é que através dela acabamos construindo uma “API” com as regras de negócio do nosso sistema, que pode ser até exposta para outros sistemas. É um lugar interessante para se colocar o controle de transação.

O livro Domain-Driven Design do Eric Evans chama ela de Application Layer, o PoEAA do Martin Fowler chama ela de Service Layer. A descrição que eles fazem da application layer e service layer é bem parecida em vários aspectos.

Ah, vc ser refere akela imagem do ‘Layered Archterure’, c/ a definição das “conceptual layers”: UI(Presentation Layer), Application Layer, Domain Layer e Infrastructure Layer??! (não estou c/ o original do Evans, estou c/ akele DDD resumido do InfoQ; depois eu dou 1 revisada na literatura do M. Fowler.)
A propósito, citando: “Application Layer - This is a thin layer which coordinates the application activity. It does not contain business logic. It does not hold the state of the business objects, but it can hold the state of an application task progress.”, creio q transpondo para o nível de micro-arquitetura a ‘Application Layer’ equivale exatamente à ‘FrontController’, não concorda?!!

[quote=Rubem Azenha]Uma camada que fica entre a camada de visualização e a camada de negócios/domínio.
Ela não contem regras de negócio nem código referente a visualização do sistema. É apenas coordena algumas atividades executada por objetos da camada de negócio…[/quote]Só 1 obs.: esta descrição (logo acima) q vc deu, se assemelha mais com a de ‘Service’ (o qual até então referencio (costumava referenciar) como Gerenciador/Manager (de Negócio), no qual devemos/podemos codificar o Fluxo de Negócio, nesta qual, IHMO, devem ser codificadas as Transações de Negócio q poder ser Estornadas. Ah, na verdade, a camada ‘Service’ deve ficar dentro do Domain (Business-Core).

[quote=derlon]Ah, vc ser refere akela imagem do ‘Layered Archterure’, c/ a definição das “conceptual layers”: UI(Presentation Layer), Application Layer, Domain Layer e Infrastructure Layer??! (não estou c/ o original do Evans, estou c/ akele DDD resumido do InfoQ; depois eu dou 1 revisada na literatura do M. Fowler.)
A propósito, citando: “Application Layer - This is a thin layer which coordinates the application activity. It does not contain business logic. It does not hold the state of the business objects, but it can hold the state of an application task progress.”, creio q transpondo para o nível de micro-arquitetura a ‘Application Layer’ equivale exatamente à ‘FrontController’, não concorda?!!
[/quote]

Nao… acho que nao tem nada haver com FrontController. Acho que tem mais haver com service layer.

Eu acredito que a service layer e a application layer tem propositos parecidos, se nao identicos.

De uma olhada nessa figura, que te mostra bem claramente o que o Rubem está explicando:

http://martinfowler.com/eaaCatalog/serviceLayer.html

[]´s
Rodrigo

@rodrigo,
Estava me referindo ao ‘Service’ do DDD (resumo do InfoQ). A propósito, relendo-o acabei me deparando c/ alguma(s) ambiguidade(s) :shock:, q vou comentar no post a seguir…
(Obs.: Aki onde eu trabalho, o site do Fowler (acredite :x) é blokeado.)

[quote=rodrigo_gomes]De uma olhada nessa figura, que te mostra bem claramente o que o Rubem está explicando:
http://martinfowler.com/eaaCatalog/serviceLayer.html[/quote]Pessoal,
Agora consegui visualizar o ‘Service Layer’*…
Neste ponto (época) o conceito de “Domain” não estava tão amadurecido ainda (p/ menos é o q a imagem conota), pois o termo ‘Domain’ isolado nem sequer aparece.
Tb gostaria de deixar claro as vários tipos de Aplicações a q o Termo ‘Application’ pode ser referido:
:arrow: Tomando o q Fowler cita “Defines an application’s boundary with a layer of services that establishes a set of available operations and coordinates the application’s response in each operation.” => Fowler se refere ao termo ‘Application’ como sendo (tudo) o q é englobado pela Service inclusive a própria ServiceLayer. Podemos concluir q esta Application (referida p/ Fowler), se refere a uma Tier (Camada Física), na qual “são centralizadas” todas as Operações de Negócio, q atualmente chamamos de Aplicação Servidora (esta contendo todas as Camadas Lógicas internas), ou Servidor de Aplicações. Um ex. disso poderia ser 1 Business-Core (+ sua Infra necessária) implementado em 1 Projeto Java, devendo este ser empacotado em um .JAR (ou .EJB, se for o caso), podendo este (Business-Core / .JAR) ser importado (incorporado) em uma ‘Aplicação Cliente’ Web, esta implementada em um projeto .WAR!
:arrow: Já na DDD de Evans, a imagem em “Layered Architecture” a conceptual ‘Application Layer’ (um camada fina, como já citado), juntamente com a ‘UI(Presentation Layer)’ denota mais claramente o Archtetural Pattern M-V-C (apesar do termo MVC não ser mencionado explicitamente no texto…). Aqui o foco, creio eu, está no funcionamento(peculariedades) da Aplicação Cliente (na qual o o (Front)Controller deve ser uma camada “burra”, q apenas “atende”(não implementa) as “ações” solicitadas, opnião compartilhada por saoj(Mentawai) ): p/ex., uma Aplicação Cliente Web em VRaptor3 redenderiza a View com JSPs/HTML e tem mecanismo próprio de dispatch (ainda q internamente use o redirect e forward da API ServletHTTP); já uma Aplicação Cliente GUI em SWING/AWT renderiza a View com JFrame/Janelas e seu macanismo de “navegabilidade” é totalmente diferente.

Em suma: DDD -> Application=>"a thin layer which coordinates…"; P of EAA -> Application=>APIde"Domínio"+Infra(+DB). What do u think?!!^^

[quote=Rubem Azenha]
Nao… acho que nao tem nada haver com FrontController. Acho que tem mais haver com service layer.
[/quote]Ah, voltando finalmente p/ falar s/ a tal ambuiguidade…
É o seguinte: Eric Evans não vê o ‘Service’ como uma “layer”. (Inclusive, procurando no texto (pelo menos no resumo da InfoQ), vc não encotra o termo “Service Layer”.)
Evans denota ‘Service’ como um tipo de Componentização de Operações de Negócio (inicialmente eu achava “de Negócio” exclusivamente) e de Operações de ‘Aplicação de Software’ (uma Aplicação enquanto Software).
:arrow: Vejamos: “The user wants to book a flights route, and asks an application service in the application layer to do so. The application tier fetches the relevant domain objects from…” -> Este “application service” percebo como sendo um (Front)Controller localizado dentro da “application layer”, a qual constumo chamar de “Aplicação Cliente” (um FrontController q atende action’s solicitadas pela request, p/ex.)
:arrow: Outra citação, esta na própria seção ‘Services’: “to transfer money from one account to another; should that function be in the sending account or the receiving account? It feels just as misplaced in either. When such a behavior is recognized in the domain, the best practice is to declare it as a Service.” Na seção anterior, ‘Entity’, Evans (muito provavelmente deve ter) reforça a importância de encapsular Operações pertinentes a uma Entidade dentro da própria Classe. No exemplo, ele busca destakar quando uma Operação/funcionalidade não pertence(é adequada) a uma Entidade ou a outra Entidade especificamente, a melhor prática é definir um ‘Service’ (uma Classe Gerenciador/Manager, p/ex.) e implentá-la nele. A minha tendencia tb é definir Fluxo de Negócio (o q tb vai de encontro ao SOA/componentização de serviços) nesta Classe|layer Service/Gerenciador. Mas, voltando ao assunto, enfim: um comportamento definido como um Service que dever ficar dentro do domain!!
Kssete, estamos indo muito off-line (mas, a discussão tá muito massa! ;-))
In brief: concluimos q o objeto ‘Service’ pode ser implementado tanto na Aplicação Cliente (como um (Front)Controller), quanto no Business-Core/API do Domain (como um ManagerService).
Todavia, considero esta abordagem/orientação muito prejudicial, pois leva à mesma confusão (principalmente por parte de Desenvolvedores principiantes), chegando até mesmo o nível de Diagramas UML, sobre Controle (o esteriótipo): se refere ao FrontController da fronteira, ou a uma Camada ‘Gerenciador’?? Considero mais salutar definir a Camada ‘Gerenciador’ (dentro da API do Domínio) como ‘Service’ (ou ManagerService) e a “Action” como um WebFrontController, até pq já existe/existia um Pattern para isto: o FrontController!

[quote=Rubem Azenha]Eu acredito que a service layer e a application layer tem propositos parecidos, se nao identicos.[/quote]Azenha,
Tendo em vista o mencionado logo acima e no post anterior, sinto muito, mas sou obrigado a discordar de vc.

O mundo de OO é um pouco maior que o senhor Evans e o senhor Fowler.
O conceito de Serviço é o de uma classe que tem uma interface definida em separado da implementação de forma a permitir vários mecanismos tanto de negocio como de infra. O SessionBean do EJB é um serviço. O padrão “Serviço” é recente, mas a utilização é antiga ( remonta ao proprio EJB 1.1)

O limite da transação é o serviço. É por isso que serviços não são repositorios e vice-versa. Para que haja modificação do estado do sistema o fluxo deve passar por um serviço.

A camada de serviços não é uma moda, é uma necessidade. Mas existem dois tipos de serviços. O de aplicação e o de dominio.
O de dominio é transacional e provoca uma alteração no estado do sistema ou implica numa regra do dominio. O de aplicação dá suporte a serviços não-funcionais como mandar emais. Estes serviços podem ser transacionais e são chamados de serviços de dominio. Estes são serviços de suporte que podem ser usados por várias aplicações diferentes.

O senhor Evans não é a melhor referencia para nomenclatura. É dele a autoria da asneira de confundir Repositorio e DAO porque não teve o mesmo cuidado que o Fowler teve quando redefiniu o termo “value object”. O repositorio-DDD pode ser um DAO, uma lista, um qualquer coisa que se assemelhe a uma coleção. O Repositorio ( padrão Repository) inventado pelo fowler não pode ser um DAO, nem Lista, etc… e isso é explicito no padrão. O ponto é : não confie muito na nomenclatura definida pelo Evans e muito menos a generalize.

Contráriamente ao que muita gente pensa a prática corrente é seguir o modelo do Fowler como indicado na figura enviada pelo Rodrigo e não o DDD. Até porque, como dizem os fans do DDD : “DDD não é sobre design patterns”.

[quote=sergiotaborda]O limite da transação é o serviço. É por isso que serviços não são repositorios e vice-versa. Para que haja modificação do estado do sistema o fluxo deve passar por um serviço.
A camada de serviços não é uma moda, é uma necessidade. [/quote]Ótimas colocações!! :thumbup:

[quote=sergiotaborda]Mas existem dois tipos de serviços. O de aplicação e o de dominio.
O de dominio é transacional e provoca uma alteração no estado do sistema ou implica numa regra do dominio. O de aplicação dá suporte a serviços não-funcionais como mandar emais. Estes serviços podem ser transacionais e são chamados de serviços de dominio. Estes são serviços de suporte que podem ser usados por várias aplicações diferentes.[/quote]Estes “serviços de suporte”: não me agrada nada chamá-los de “Serviços de aplicação”. :frowning: (Sei, sou suspeito p/ falar, pois sou 1 grande fã do DDD! =P) Prefiro colocá-los num Pacote ‘InfraServices’ e chamá-lo de ‘utilInfraSrvc’, p/ex., ‘mensagemInfraSrvc’: para envio - usando o DIP - é transparente para o Domain se a Msg é enviada via E-Mail, ou de outra forma. (Só ficou confusa esta parte: “O de aplicação dá suporte a serviços não-funcionais como mandar emais. Estes serviços podem ser transacionais e são chamados de serviços de dominio.”.)

[quote=sergiotaborda]O senhor Evans não é a melhor referencia para nomenclatura. É dele a autoria da asneira de confundir Repositorio e DAO porque não teve o mesmo cuidado que o Fowler teve quando redefiniu o termo “value object”. O repositorio-DDD pode ser um DAO, uma lista, um qualquer coisa que se assemelhe a uma coleção.[/quote]Não consta, pelo menos no resumo do InfoQ, nada sobre o “Repository ser um DAO”. Mas, volto a citar: “A Repository may contain detailed information used to access the infrastructure, but its interface should be simple.” e “… the implementation of a repository can be closely liked to the infrastructure, but that the repository interface will be [color=red]pure[/color] domain model.” Então vemos que foram usando os verbos “may” e “can” (ou seja, “pode”) e não foi usado ‘must’ (‘deve’/deveria). Ou seja, ficou claro ele q denota 'Repository’s como um tipo de Arquivo Lógico.
Vejo a coisa da seguinte forma (e até o pessoal do princípio KISS e/ou agilistas vão concordar): os Repository’s podem ter um atributo ‘EntityManager’ (do JPA, o qual inclusive alega abstrair/encapsular a DAO) injetado por um @PersistenceContex; caso sejam percebidos “gargalos” em alguns Objetos DomainModel, seu Repository poderia então usar uma DAO, c/ abordagem JDBC puro p/ex., sendo esta DAO implementada num Pacote (totalmente) fora do Domain.

[quote=sergiotaborda] O Repositorio ( padrão Repository) inventado pelo fowler não pode ser um DAO, nem Lista, etc… e isso é explicito no padrão. O ponto é : não confie muito na nomenclatura definida pelo Evans e muito menos a generalize.
[/quote]Bem, isto já um questão intrerpretativa sua. Na obra de Evans, as únicas coisas q eu não gostei foram: 1. A ambiguidade, sobre Aplicação, entre o termos “software application” (Aplicação de Software, como um todo) e “application layer” (q, na minha interpretação, entendo como o FrontController); e 2. um equívoco conceitual, muito além de uma nomeclatura ambígua, de definir um ‘Service’ nesta dita “application layer”. (O que é ainda pior.) :x
Mas, Q bom o Fowler ser mais assertivo/acurado. (É p/ isso q eu sou muito fã dele! :stuck_out_tongue: )

(Ah, só uma Obs.: como o casal Freeman sempre fala: Os Padrões não são “inventados”, são “descobertos”!)

“repository can be closely liked to the infrastructure”

O erro é o “can”. It can not.
O repositorio não pode ter detalhes de infraestrutura.
Se tiver é uma implementação gambiarra. O padrão Repository sempre delega esses detalhes a um outro objeto.

Isso é o que deve ser. Mas não é isso que o Evans diz. Quando ele diz que “pode” significa que o repositorio pode ser o proprio dao ou o proprio entitymanager. Significa que o repositorio pode ser uma interface implementada pelo DAO. etc… o numero de aberrações possivel é imenso.
O ponto é que tudo isso são implementações erradas do padrão Repository.

O problema é que as pessoas confundem “Repository” o padrão com “repository” do DDD. Enquanto todos as implementações do padrão repository são repositorios-DDD nem todos os repositorios-DDD são implementações do padrão Repository ( por exemplo, List )

[quote=sergiotaborda] O Repositorio ( padrão Repository) inventado pelo fowler não pode ser um DAO, nem Lista, etc… e isso é explicito no padrão. O ponto é : não confie muito na nomenclatura definida pelo Evans e muito menos a generalize.
[/quote]Bem, isto já um questão intrerpretativa sua. [/quote]

Não. É uma conclusão que vc mesmo pode chegar estudando o trabalho de ambos. Mas leia o livro do evans não o exceto num site.