Transação em Repository  XML
Índice dos Fóruns » Arquitetura de Sistemas
Autor Mensagem
j0nny
GUJ Master
[Avatar]

Membro desde: 19/09/2009 00:01:57
Mensagens: 1121
Localização: Blumenau - SC
Offline

Estudando e aplicando mais o repository nas entidades, cheguei à um impasse: como controlar minhas transações nos repositórios (sem usar Spring)?

Exemplo:



Como controlaria a transação nesse caso?

This message was edited 1 time. Last update was at 06/02/2011 22:09:01


@jntsdaniel
github.com/jonatasdaniel

---

AndOrm - Framework ORM para Android
http://github.com/jonatasdaniel/andorm
[WWW]
esmiralha
JavaEvangelist

Membro desde: 19/07/2006 09:04:42
Mensagens: 402
Offline

Acho que você está confundindo o propósito do pattern Repository em DDD. Um Repository simula uma coleção de objetos em memória. Ele sabe retornar objetos baseado em algum critério de busca, persistir um objeto recém criado e atualizar objetos existentes. Métodos como sacar(), depositar() não pertencem a um Repositório e sim à própria Entidade. Para um exemplo de uma interface de Repository: http://dddsample.sourceforge.net/xref/se/citerus/dddsample/domain/model/cargo/CargoRepository.html

A transação como sempre deve ser controlada na camada de Serviço e não no Repository.
j0nny
GUJ Master
[Avatar]

Membro desde: 19/09/2009 00:01:57
Mensagens: 1121
Localização: Blumenau - SC
Offline

esmiralha wrote:Acho que você está confundindo o propósito do pattern Repository em DDD. Um Repository simula uma coleção de objetos em memória. Ele sabe retornar objetos baseado em algum critério de busca, persistir um objeto recém criado e atualizar objetos existentes. Métodos como sacar(), depositar() não pertencem a um Repositório e sim à própria Entidade. Para um exemplo de uma interface de Repository: http://dddsample.sourceforge.net/xref/se/citerus/dddsample/domain/model/cargo/CargoRepository.html

A transação como sempre deve ser controlada na camada de Serviço e não no Repository.


Acho que vc não entendeu a aplicação do pattern nesse caso:
http://blog.caelum.com.br/repository-seu-modelo-mais-orientado-a-objeto/

Meu modelo NUNCA vai conhecer o DAO, o DAO vai implementar meu Repository, mas como não conheço o dao, e as ações de persistencia ficarão a cargo do repository, preciso ter as transações em algum lugar, aí que entra minha pergunta.

@jntsdaniel
github.com/jonatasdaniel

---

AndOrm - Framework ORM para Android
http://github.com/jonatasdaniel/andorm
[WWW]
YvGa
Virtual Machine Man

Membro desde: 07/03/2007 15:58:16
Mensagens: 518
Offline

Eu, quando nao uso spring, ponho as transacoes nos services, que sao quem orquestra toda a operacao. No seu caso eu nao usaria a conta para fazer a transferencia e sim uma outra entidade ou um service mesmo, o qual seria o responsavel pelo saque numa conta e deposito na outra.

Pessoalmente acho que uma conta nao deveria ter a responsabilidade de fazer o deposito/transferencia em outra.

Paulo Borio
j0nny
GUJ Master
[Avatar]

Membro desde: 19/09/2009 00:01:57
Mensagens: 1121
Localização: Blumenau - SC
Offline

YvGa wrote:Eu, quando nao uso spring, ponho as transacoes nos services, que sao quem orquestra toda a operacao. No seu caso eu nao usaria a conta para fazer a transferencia e sim uma outra entidade ou um service mesmo, o qual seria o responsavel pelo saque numa conta e deposito na outra.

Pessoalmente acho que uma conta nao deveria ter a responsabilidade de fazer o deposito/transferencia em outra.


Mas na minha arquitetura, não tenho service, é só assim:

Controller - Entidades - Repositorios

@jntsdaniel
github.com/jonatasdaniel

---

AndOrm - Framework ORM para Android
http://github.com/jonatasdaniel/andorm
[WWW]
Oenning
Thread.start()
[Avatar]

Membro desde: 11/05/2007 19:16:26
Mensagens: 48
Offline

Acho que seu código deveria ser assim, não?



Se não me engano é nesses casos que você usa uma UnitOfWork. Cria ela no inicio da HttpRequest, injeta nos seus repositorios e comita no final requisição.

This message was edited 1 time. Last update was at 09/02/2011 11:19:42


Blog: http://blog.oenning.eti.br
Twitter: @goenning
[WWW]
j0nny
GUJ Master
[Avatar]

Membro desde: 19/09/2009 00:01:57
Mensagens: 1121
Localização: Blumenau - SC
Offline

Oenning wrote:Acho que seu código deveria ser assim, não?



Se não me engano é nesses casos que você usa uma UnitOfWork. Cria ela no inicio da HttpRequest, injeta nos seus repositorios e comita no final requisição.


Bem isso, mas no caso de um repositório ser uma interface, eu injetaria como?

@jntsdaniel
github.com/jonatasdaniel

---

AndOrm - Framework ORM para Android
http://github.com/jonatasdaniel/andorm
[WWW]
Oenning
Thread.start()
[Avatar]

Membro desde: 11/05/2007 19:16:26
Mensagens: 48
Offline

Você injeta na implementação, pelo visto no seu caso é uma DAO

Blog: http://blog.oenning.eti.br
Twitter: @goenning
[WWW]
j0nny
GUJ Master
[Avatar]

Membro desde: 19/09/2009 00:01:57
Mensagens: 1121
Localização: Blumenau - SC
Offline

Oenning wrote:Você injeta na implementação, pelo visto no seu caso é uma DAO


Mas meu entityManager, por exemplo, seria injetado no DAO através de DI. Aí não vejo uma solução de capturar ele.

@jntsdaniel
github.com/jonatasdaniel

---

AndOrm - Framework ORM para Android
http://github.com/jonatasdaniel/andorm
[WWW]
Oenning
Thread.start()
[Avatar]

Membro desde: 11/05/2007 19:16:26
Mensagens: 48
Offline

Agora você me pegou, eu programo em C#, mas acredito que em Java seja parecido.
Para mim, a injeção vem através do Construtor. Fica assim:



No meu framework DI eu configuro como ele deve injetar uma session.

Quando eu trabalhei com spring+java, bastava anotar a propriedade com algo assim no meu DAO:



Não sei como estão as coisas atualmente.

Blog: http://blog.oenning.eti.br
Twitter: @goenning
[WWW]
j0nny
GUJ Master
[Avatar]

Membro desde: 19/09/2009 00:01:57
Mensagens: 1121
Localização: Blumenau - SC
Offline

É isso que quero dizer, até este ponto, ok, mas como é o container de DI que vai injetar, eu não vou ter a transaction, entende?

@jntsdaniel
github.com/jonatasdaniel

---

AndOrm - Framework ORM para Android
http://github.com/jonatasdaniel/andorm
[WWW]
Oenning
Thread.start()
[Avatar]

Membro desde: 11/05/2007 19:16:26
Mensagens: 48
Offline

Veja se isso ajuda
http://community.jboss.org/wiki/OpenSessioninView#Using_an_interceptor

Ele abre uma transaction no inico da request e comita no final dela.
Sendo assim, durante a requisição, quando seus DAO fizeram INSERT/UPDATE, você vai ter uma transação rodando.

Desculpe-me por não ter mais detalhes, faz tempo que não programo em Java.

Blog: http://blog.oenning.eti.br
Twitter: @goenning
[WWW]
j0nny
GUJ Master
[Avatar]

Membro desde: 19/09/2009 00:01:57
Mensagens: 1121
Localização: Blumenau - SC
Offline

Oenning wrote:Veja se isso ajuda
http://community.jboss.org/wiki/OpenSessioninView#Using_an_interceptor

Ele abre uma transaction no inico da request e comita no final dela.
Sendo assim, durante a requisição, quando seus DAO fizeram INSERT/UPDATE, você vai ter uma transação rodando.

Desculpe-me por não ter mais detalhes, faz tempo que não programo em Java.


Legal essa abordagem, vou dar uma estudada.

@jntsdaniel
github.com/jonatasdaniel

---

AndOrm - Framework ORM para Android
http://github.com/jonatasdaniel/andorm
[WWW]
peczenyj
Moderador
[Avatar]

Membro desde: 26/03/2006 23:25:37
Mensagens: 3191
Localização: Rio de Janeiro
Offline

evite transações e implemente transações compensatórias.

vera que o design pode ficar mais simples.

nesse caso: vc quer transferir de A para B.

vc "saca" de A
vc transfere para B
deu problema? vc extorna para A, depois de X minutos -- como acontece na prática com um DOC ou TED.

não consegue extornar por problema no banco? vc tem um belo problema.

se o Saca e Transfere forem eventos, a coisa fica bem interessante.

http://martinfowler.com/eaaDev/EventSourcing.html

ai perceba o seguinte: imagine que vc sacou 2x 200 reais ao mesmo tempo e vc tem 201 reais na conta. simultaneo mesmo. provavelmente vc vai atender aos dois requests e, quando ficar negativo e o cara náo puder ficar negativo mete uma multa nele.

mas ai vc não quer que isso aconteça. vc vai ter que implementar algum recurso de "lock" para evitar problemas de simultaneidade. Por exemplo, vc pode gerar um Token de autorização por conexao sendo que o Token que vale é sempre um, que seria salvo em uma estrutura de dados xpto. na hora de responder ao saque vc pode ver se o Token é valido e como só pode haver um... no fim tudo é uma questão de "quem quer rir tem que fazer rir".

http://pacman.blog.br

'Não importa quanto alguém se dedique à tarefa. Ninguém consegue fazer a água da cascata cair para cima.'
[WWW]
esmiralha
JavaEvangelist

Membro desde: 19/07/2006 09:04:42
Mensagens: 402
Offline

peczenyj wrote:evite transações e implemente transações compensatórias.

vera que o design pode ficar mais simples.

nesse caso: vc quer transferir de A para B.

vc "saca" de A
vc transfere para B
deu problema? vc extorna para A, depois de X minutos -- como acontece na prática com um DOC ou TED.

não consegue extornar por problema no banco? vc tem um belo problema.

se o Saca e Transfere forem eventos, a coisa fica bem interessante.

http://martinfowler.com/eaaDev/EventSourcing.html

ai perceba o seguinte: imagine que vc sacou 2x 200 reais ao mesmo tempo e vc tem 201 reais na conta. simultaneo mesmo. provavelmente vc vai atender aos dois requests e, quando ficar negativo e o cara náo puder ficar negativo mete uma multa nele.

mas ai vc não quer que isso aconteça. vc vai ter que implementar algum recurso de "lock" para evitar problemas de simultaneidade. Por exemplo, vc pode gerar um Token de autorização por conexao sendo que o Token que vale é sempre um, que seria salvo em uma estrutura de dados xpto. na hora de responder ao saque vc pode ver se o Token é valido e como só pode haver um... no fim tudo é uma questão de "quem quer rir tem que fazer rir".


Entendo e respeito seu ponto de vista, mas... acho que eu só partiria para uma abordagem desse tipo se houvesse uma ótima razão e para mim um design mais simples por si só não seria uma razão boa o bastante, pois a simplicidade está nos olhos do observador (e aos meu olhos eu ainda não tenho certeza que manter checkpoints e undos seria um design realmente mais simples). TPM alto e particionamento seriam boas razões para desprezar o controle transacional oferecido pelo banco e implementar outro na unha.

Também nunca entendi como Event Sourcing se diferencia da simples implementação do pattern Command na camada de Domínio. Preciso ler mais sobre o assunto.
 
Índice dos Fóruns » Arquitetura de Sistemas
Ir para:   
Powered by JForum 2.1.8 © JForum Team