CpBT and transactions

5 views
Skip to first unread message

Argons

unread,
Dec 17, 2009, 7:17:03 PM12/17/09
to uNhAddIns
Tengo un problema al utilizar CpBT. Bueno, estoy siguiendo el ejemplo
SessionManagement y tengo una arquitectura parecida a dicho ejemplo.
Tengo una clase Repositorio<T> parecida a la del ejemplo:

[PersistenceConversational(MethodsIncludeMode =
MethodsIncludeMode.Implicit)]
public class Repositorio<T> : IRepositorio<T>
{
private readonly ISessionFactory nhFactory;

#region " Constructor "

public Repositorio(ISessionFactory factory)
{
nhFactory = factory;
}

#endregion

#region " Propiedades "

public ISession Sesion
{
get { return nhFactory.GetCurrentSession(); }
}

#endregion

#region " Métodos Publicos "

[PersistenceConversation(ConversationEndMode = EndMode.End)]
public void Actualizar(T entidad)
{
Sesion.SaveOrUpdate(entidad);
}

[PersistenceConversation(ConversationEndMode = EndMode.End)]
public void Eliminar(T entidad)
{
Sesion.Delete(entidad);
}

............. etc

tengo otra clase que la llamé BaseNegocio<T> (donde T es la entidad de
negocio) que contiene un campo de tipo IRepositorio que es cargado en
el load con windsor. Contiene casi las mismas operaciones que el
repositorio pero con la diferencia q esta se encarga de realizar
validaciones sobre las entidades antes de realizar la operacion, y
otras cosas mas. La cosa es que tengo toda una capa de negocios que
heredan de esta clase base, todo funciona bien mientras grabo una sola
entidad, el problema ocurre cuando trato de grabar 2 o mas clases, de
esta forma:

public void GrabarNuevaPersona()
{
PersonaNegocio lnPersona = new PersonaNegocio(); // Hereda de
BaseNegocio
LogNegocio lnLog = new LogNegocio(); // Herda de BaseNegocio

lnPersona.Insertar(persona);
lnLog.Insertar(log);
}

Graba las 2 entidades bien, pero si digamos ocurre un problema con
log, no hace un rollback de la transacción. Cómo puedo resolver mi
problema? sé que estoy haciendo algo mal pero realmente no puedo
detectar donde.

Help please and thanks in advance for any advice/help.

Ariel

Gustavo Ringel

unread,
Dec 18, 2009, 4:44:44 AM12/18/09
to unhaddins
Hi, this is an English group, and we prefer English as the way of communication, luckily we have some commiters and people helping which doesn't speak spanish.

I think your problem may be the strategy for ID's, are you using Identity? in this case some things are saved even when you don't want to. It is a limitation of using identity with this kind of solutions, you should go for hilo / guid.comb, and then nothing is going to be saved to the database until you flush and close the session using the EndMode.End method.

If you need to abort the conversation you need an EndMode.Abort method and you will get a Rollback.

As a side not, even if it is possible i don't think putting the conversation in the Repository Level is a good strategy, Model/Services or in a few cases Presenters are the candidates to manage the conversation, it is an infrastructure concept and not a Data Access concept.

Gustavo.

2009/12/18 Argons <arg...@gmail.com>

Argons

unread,
Dec 18, 2009, 7:22:52 AM12/18/09
to uNhAddIns
Thanks for the reply, first sorry for the spanish, it's because i
can't express myself very well in english.
You're right I'm using identity for the ID's, but I think I found what
the problem is. Like you said using conversations in the repository
level is the problem because my operations become atomic, when I call
lnPersona.Insertar(persona) the transaction is commited and when I
call lnLog.Insertar(log) opens another transaction because "Insertar"
is decorated with EndMode.End. Well I think that's the problem, right?

I tried to use a transation like this:

public void GrabarNuevaPersona()
{
PersonaNegocio lnPersona = new PersonaNegocio();

LogNegocio lnLog = new LogNegocio();

using(var transaction = Sesion.BeginTransaction())
{
lnPersona.Insertar(persona);
lnLog.Insertar(log);
}
}

But the transaction is closed after Insertar(persona).

Well I think the only solution is change de "decoration" to each
Service instead of the repository and decorate this method with
EndMode.End. Or is there another way to do it?

Thanks for the help

Gustavo Ringel

unread,
Dec 18, 2009, 8:55:56 AM12/18/09
to unhaddins
You should decorate the classes that are in charge of the transactions.
In general they are Application Services / Models / Presenters...
For little CRUD applications which are not expected to change the repositories maybe decorated.

Gustavo.
Reply all
Reply to author
Forward
0 new messages