You are viewing a plain text version of this content. The canonical link for it is here.
Posted to ojb-user@db.apache.org by Bruno CROS <br...@gmail.com> on 2006/05/06 00:55:04 UTC

Avoiding Persistence Broker Leak

  Hi Armin,

Thanks for the idea to detect broker leak. It will show some bad coded
methods, even they have been checked : commit never reached, broker not
closed... no commit/abort !!! (find one, arghh )

Meanwhile,  there was still some "open broker detected". When i look into
code, i found some old methods that were reading objects, with a dedicated
transaction. I known now that this transaction is not necessary, and I know
now it's even unwanted ! It seems to burn connections/brokers.

So i add a little check to my "getTransaction()" method. Now, it searches
for a current transaction, and il found, throw a "Already open
transaction".  This let us detect the standalone update method (opening and
closing Transaction), who are called inside an already open  Transaction (as
the old bad reads methods was called by update methods). Everything gets ok
now.

May be it can be an developpment setup to avoid broker leak due to the
double opening Transaction (with same broker)

Thanks a lot. Again.

Regards

Re: Avoiding Persistence Broker Leak

Posted by Bruno CROS <br...@gmail.com>.
On 5/6/06, Edson Carlos Ericksson Richter <
edson.richter@mgrinformatica.com.br> wrote:
>
> I've used a similar solution, but when I get a broker, first I check if
> one broker was already taken for this thread (and a usage counter is
> incremented).
> Then, when I start one operation, I just check if there is not already a
> transaction. If there is no transaction, then I open one. Finally, when
> I ask to close the broker, a usage counter for current thread is
> decremented, and if it's zero, then broker is really closed.


Oh, well i did something like that with a personal getPersistenceBroker()
method and a closePersistenceBrokerIfNeeded(PersistenceBroker broker).
Those wethods are called to execute read operations. getPersistenceBroker()
look at a current Transaction, if found, the broker of the transaction is
returned, else a new broker is created (*).
ClosePersistenceBrokerIfNeeded(broker) look at a current transaction too, if
found do not close anything, else close the broker in parameter ( that's
because broker of transaction will be closed by a commit() or an abort().

I think we have done the same kind of system.


This technique allow:
>
> - Cross object transactions in same thread
> - Avoid begin more than one transaction per broker
> - Obligate to always open one transaction, what guarantee standard
> behaviour independent of developer personal preferences (important for
> groups). So, I can reuse a component written by another programmer
> because I know if he execute some operation in database, I'll be in same
> transaction.
> - When no more object is using a broker, the broker is automatically
> closed.


(*)Those who can differ is that, my read operation methods, borrow(or
create) and give back the broker. Running transaction, it's the same broker
used for all (to work with not written objects) and if no transaction,
objects are read with any created broker. I just understand the advantage to
use only one broker for several stacked read calls : the cache. May be i
will change to you technique, but i have too many getDefaultBroker left in
code at this moment.

Resuming, all my code finish in one class that is responsible to take a
> broker, start a transaction (if needed), execute operation, and close
> broker (if there is no more objects using it, of course).
>
> When I execute one operation, I delegate to Action method to start
> transaction, commit or rollback. So, every action in my code has
> following structure:



Yep, programmers must known count now ;-). arrfff..

public void actionPerformed(ActionEvent evt) {
> try {
>    MyPersonBrokerUC.beginTransaction(); // starts a transaction and
> increments usage (to 1) for this thread
>    MyPersonBrokerUC.store(somePerson); // detect if is a insert or an
> update (increments usage to 2) and does the job (return broker and
> decrements to 1 again). Will use same broker and transaction started above
>    OtherPersonUC.dealWithNewPersons(somePerson); // will run under same
> transaction (increments usage to 2, execute operation, and decrements to
> 1 again). I don't even need to know if there is a bunch of another calls
> inside this method: all will run under same transaction.
>    MyPersonBrokerUC.commitTransaction(); // commit the transaction and
> decrements usage (to 0, so broker is really closed)
> } catch(Exception e) {
>    MyPersonBrokerUC.rollbackTransaction(); // rollback the transaction
> and decrements usage (to 0, so broker is really closed)
>    DebugUtil.handleException(e);
> }
> }
>
> UC (use cases) classes never begin, commit or rollback: it's a Action
> task. Because a task always execute under unique thread, there is not
> problems (if you wish to execute async operation, just start transaction
> inside new thread). Works for MVC-Web development (a Servlet or a JSP
> will be the "action" in this case).


generally, i avoid manipulating O/R mapped objects in jsp.

Thanks to try...catch structure, there is no way to forget a broker
> open, neither a transaction open.



that' a very good assurance.

Only one cons for this: when debugging, don't try to "fix and continue",
> because you will get broken brokers and transactions, leading to dead
> lock and fatally to stop and restart.


same problem occurs with others techniques.

OT: humm, trying to explain just in words this appear to be really
> complicated, but in fact, it isn't. May be sometime I get spare time to
> create some nice Sequence and Collaboration diagrams to explain this....


Thanks a lot for this. Check many methods without such a technique, is very
long... OJB developpements are shorter !!

> Best regards,



Best regards.


Edson Richter
>
>
>
> Bruno CROS escreveu:
> >  Hi Armin,
> >
> > Thanks for the idea to detect broker leak. It will show some bad coded
> > methods, even they have been checked : commit never reached, broker not
> > closed... no commit/abort !!! (find one, arghh )
> >
> > Meanwhile,  there was still some "open broker detected". When i look
> into
> > code, i found some old methods that were reading objects, with a
> > dedicated
> > transaction. I known now that this transaction is not necessary, and I
> > know
> > now it's even unwanted ! It seems to burn connections/brokers.
> >
> > So i add a little check to my "getTransaction()" method. Now, it
> searches
> > for a current transaction, and il found, throw a "Already open
> > transaction".  This let us detect the standalone update method
> > (opening and
> > closing Transaction), who are called inside an already open
> > Transaction (as
> > the old bad reads methods was called by update methods). Everything
> > gets ok
> > now.
> >
> > May be it can be an developpment setup to avoid broker leak due to the
> > double opening Transaction (with same broker)
> >
> > Thanks a lot. Again.
> >
> > Regards
> >
>
>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: ojb-user-unsubscribe@db.apache.org
> For additional commands, e-mail: ojb-user-help@db.apache.org
>
>

Re: Avoiding Persistence Broker Leak

Posted by Edson Carlos Ericksson Richter <ed...@mgrinformatica.com.br>.
I've used a similar solution, but when I get a broker, first I check if 
one broker was already taken for this thread (and a usage counter is 
incremented).
Then, when I start one operation, I just check if there is not already a 
transaction. If there is no transaction, then I open one. Finally, when 
I ask to close the broker, a usage counter for current thread is 
decremented, and if it's zero, then broker is really closed.

This technique allow:

 - Cross object transactions in same thread
 - Avoid begin more than one transaction per broker
 - Obligate to always open one transaction, what guarantee standard 
behaviour independent of developer personal preferences (important for 
groups). So, I can reuse a component written by another programmer 
because I know if he execute some operation in database, I'll be in same 
transaction.
 - When no more object is using a broker, the broker is automatically 
closed.

Resuming, all my code finish in one class that is responsible to take a 
broker, start a transaction (if needed), execute operation, and close 
broker (if there is no more objects using it, of course).

When I execute one operation, I delegate to Action method to start 
transaction, commit or rollback. So, every action in my code has 
following structure:

public void actionPerformed(ActionEvent evt) {
  try {
    MyPersonBrokerUC.beginTransaction(); // starts a transaction and 
increments usage (to 1) for this thread
    MyPersonBrokerUC.store(somePerson); // detect if is a insert or an 
update (increments usage to 2) and does the job (return broker and 
decrements to 1 again). Will use same broker and transaction started above
    OtherPersonUC.dealWithNewPersons(somePerson); // will run under same 
transaction (increments usage to 2, execute operation, and decrements to 
1 again). I don't even need to know if there is a bunch of another calls 
inside this method: all will run under same transaction.
    MyPersonBrokerUC.commitTransaction(); // commit the transaction and 
decrements usage (to 0, so broker is really closed)
  } catch(Exception e) {
    MyPersonBrokerUC.rollbackTransaction(); // rollback the transaction 
and decrements usage (to 0, so broker is really closed)
    DebugUtil.handleException(e);
  }
}

UC (use cases) classes never begin, commit or rollback: it's a Action 
task. Because a task always execute under unique thread, there is not 
problems (if you wish to execute async operation, just start transaction 
inside new thread). Works for MVC-Web development (a Servlet or a JSP 
will be the "action" in this case).

Thanks to try...catch structure, there is no way to forget a broker 
open, neither a transaction open.

Only one cons for this: when debugging, don't try to "fix and continue", 
because you will get broken brokers and transactions, leading to dead 
lock and fatally to stop and restart.


OT: humm, trying to explain just in words this appear to be really 
complicated, but in fact, it isn't. May be sometime I get spare time to 
create some nice Sequence and Collaboration diagrams to explain this....


Best regards,

Edson Richter



Bruno CROS escreveu:
>  Hi Armin,
>
> Thanks for the idea to detect broker leak. It will show some bad coded
> methods, even they have been checked : commit never reached, broker not
> closed... no commit/abort !!! (find one, arghh )
>
> Meanwhile,  there was still some "open broker detected". When i look into
> code, i found some old methods that were reading objects, with a 
> dedicated
> transaction. I known now that this transaction is not necessary, and I 
> know
> now it's even unwanted ! It seems to burn connections/brokers.
>
> So i add a little check to my "getTransaction()" method. Now, it searches
> for a current transaction, and il found, throw a "Already open
> transaction".  This let us detect the standalone update method 
> (opening and
> closing Transaction), who are called inside an already open  
> Transaction (as
> the old bad reads methods was called by update methods). Everything 
> gets ok
> now.
>
> May be it can be an developpment setup to avoid broker leak due to the
> double opening Transaction (with same broker)
>
> Thanks a lot. Again.
>
> Regards
>