You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@struts.apache.org by Sean Schofield <se...@schof.com> on 2004/09/17 20:43:57 UTC

Idea for chain and DB transactions

I have a problem and a proposed solution.  I would greatly appreciate any feedback about the proposed solution.

Problem:
=======
I'm currently using a Struts application with a connection pool (using DBCP as supplied by Tomat).  When a database update is needed, the Struts actions will call the facade which will talk to my service layer (currently POJO's which handle business logic.)  My service layer in turn talks to the appropriate DAO.  Each of these DAO's extends from a common abstract class that provides basic functionality including obtaining a connection from the DataSource (via the pool).  A key aspect of my design is that some updates are in distinct areas of the database and so I have different DAO's for each area (ex. one for "workflow" on for "document.")  

As currently implemented I am unable to take advantage of transactions because the two DAOs will be getting a connection indepently from the pool and they will most likely not obtain the connection each time.  If I could just get the same connection each time, then I could use setAutoCommit(false).

Proposed Solution:
==============
I'm thinking I could set up a few chains for the various kind of updates.  The chains would be called by the POJO service layer (instead of calling the DAO's directly.)  The first Command in the chain would be to indentify all database updates in the chain as needing transactions.  This would be done through a static method on a new object called TransactionManager.  Basically I would have a hashtable that would maintain connections for the duration of the chain.  The connections would be stored by the current thread (use that as the key to the table.)  

Then when a command down the line needs a database connection, it would first check to see if there is one already set aside for it to use.  Actually the command would call the DAO and the DAO would check.  The command would also be decorated by a custom wrapper so that if the DAO's try to close the connection, I'll ignore it.  Then when the chain does the post processing in reverse order.  So the last clean up step will be to check for my custom DAOException.  If there is one, then rollback, otherwise commit.  Finally, the connection is removed from the TransactionManager.

I think this might be crazy enough to work.  I know we could allways use EJB and get transactions but that might be overkill since the volume is very light (this is custom software for a government agency not ecommerce.)  Please let me know what you think.  A big question I have is about storing and retrieving the datbase connection using the current thread as the key to a hashtable.  Also, I know that I will have to be careful with thread synchronization.

Thanks,
sean


Re: Idea for chain and DB transactions

Posted by Sean Schofield <se...@schof.com>.
Craig,

Thanks for your response.  The main problem with that idea would be that I 
would have to count on the connection being in the context and the command 
would have to directly access the database.  I was thinking that my commands 
would be simple "facades" to the DAO layer.  That way I could leave my DAO's 
intact (and would be free to change them when I needed.)

Why not have the first command in the chain get a connection from the pool 
and store it in ThreadLocal?  Then the DAO's can use the connection without 
the commands having to deal with the connection or the datbase logic.  Do 
you see any drawbacks to this approach?

By the way, I do plan on still using postProcess() to the return the 
connection to the pool.


Atta,

You could write your own custom plugin that would initialize the chain 
stuff.  Note that commons-chain is its own project and does not have to be 
directly tied to Struts.  The struts-chain effort is going to use 
commons-chain to handle some of the behind the scenes struts implementation. 
Once its available you can probably piggyback off their plugin to initialize 
the chain stuff.

In the meantime, write your own plugin (use the one in struts-chain as a 
basis).  The plugin should store the Catalog in servlet context and can be 
used by your actions, etc.  Take a look at the CatalogConfiguratorPlugin 
that is in the contrib section of the nightly source tarball.

HTH,
sean


----- Original Message ----- 
From: "atta-ur rehman" <at...@gmail.com>
To: "Struts Users Mailing List" <us...@struts.apache.org>; "Craig McClanahan" 
<cr...@gmail.com>
Sent: Saturday, September 18, 2004 12:30 PM
Subject: Re: Idea for chain and DB transactions


> Craig,
>
> That sounds pretty exciting. Now, how could I, if at all, incorporate
> this Filter/Chian functionality in my existing Struts 1.1 app?
>
> ATTA
>
>
> On Sat, 18 Sep 2004 07:19:45 -0700, Craig McClanahan <cr...@gmail.com> 
> wrote:
>> Commons Chain (on which Struts Chain is based) has a design pattern
>> built in for the general case were one command in the chain wants to
>> allocate resources that will be required for later commands in the
>> chain, plus the ability to clean up that resource when the chain
>> completes.  See the Javadocs for org.apache.commons.chain.Filter.
>>
>> For example, assume you want to allocate a connection from a
>> connection pool defined as a JNDI resource (the same principle applies
>> to any other sort of resource allocation factory) -- create a Filter
>> with the following functionality:
>>
>> * In the execute() method, acquire a reference to the data source,
>>   acquire a connection, and store it as an attribute in the context.
>>
>>   public boolean execute(Context context) throws Exception {
>>       InitialContext ic = new InitialContext();
>>       DataSource ds = (DataSource)
>>         ic.lookup("java:comp/env/jdbc/CustomerDatabase");
>>       Connection conn = ds.getConnection();
>>       context.put("connection", conn);
>>       return false;
>>   }
>>
>> * In the postprocess() method, call close() on the connection,
>>   which returns it to the pool:
>>
>>   public boolean postprocess(Context context, Exception exception) {
>>     Connection conn = (Connection) context.get("connection");
>>     conn.close();
>>     return false;
>>   }
>>
>>   Note that the postprocessing method will be called even if an
>> exception was thrown in a
>>   subsequently called command.
>>
>> In all other commands, the execute() method can simply use the
>> allocated resource, without having to care how it got there:
>>
>>   public boolean execute(Context context) throws Exception {
>>     Connection conn = (Connection) context.get("connection");
>>     ... use the connection to perform database transactions ...
>>   }
>>
>> Using this design, you don't have to worry about external storage of
>> the allocated resources -- just store them under a well known
>> attribute name in the context object that is passed in to all
>> commands.
>>
>> Craig
>>
>> On Fri, 17 Sep 2004 14:43:57 -0400, Sean Schofield
>>
>>
>> <se...@schof.com> wrote:
>> > I have a problem and a proposed solution.  I would greatly appreciate 
>> > any feedback about the proposed solution.
>> >
>> > Problem:
>> > =======
>> > I'm currently using a Struts application with a connection pool (using 
>> > DBCP as supplied by Tomat).  When a database update is needed, the 
>> > Struts actions will call the facade which will talk to my service layer 
>> > (currently POJO's which handle business logic.)  My service layer in 
>> > turn talks to the appropriate DAO.  Each of these DAO's extends from a 
>> > common abstract class that provides basic functionality including 
>> > obtaining a connection from the DataSource (via the pool).  A key 
>> > aspect of my design is that some updates are in distinct areas of the 
>> > database and so I have different DAO's for each area (ex. one for 
>> > "workflow" on for "document.")
>> >
>> > As currently implemented I am unable to take advantage of transactions 
>> > because the two DAOs will be getting a connection indepently from the 
>> > pool and they will most likely not obtain the connection each time.  If 
>> > I could just get the same connection each time, then I could use 
>> > setAutoCommit(false).
>> >
>> > Proposed Solution:
>> > ==============
>> > I'm thinking I could set up a few chains for the various kind of 
>> > updates.  The chains would be called by the POJO service layer (instead 
>> > of calling the DAO's directly.)  The first Command in the chain would 
>> > be to indentify all database updates in the chain as needing 
>> > transactions.  This would be done through a static method on a new 
>> > object called TransactionManager.  Basically I would have a hashtable 
>> > that would maintain connections for the duration of the chain.  The 
>> > connections would be stored by the current thread (use that as the key 
>> > to the table.)
>> >
>> > Then when a command down the line needs a database connection, it would 
>> > first check to see if there is one already set aside for it to use. 
>> > Actually the command would call the DAO and the DAO would check.  The 
>> > command would also be decorated by a custom wrapper so that if the 
>> > DAO's try to close the connection, I'll ignore it.  Then when the chain 
>> > does the post processing in reverse order.  So the last clean up step 
>> > will be to check for my custom DAOException.  If there is one, then 
>> > rollback, otherwise commit.  Finally, the connection is removed from 
>> > the TransactionManager.
>> >
>> > I think this might be crazy enough to work.  I know we could allways 
>> > use EJB and get transactions but that might be overkill since the 
>> > volume is very light (this is custom software for a government agency 
>> > not ecommerce.)  Please let me know what you think.  A big question I 
>> > have is about storing and retrieving the datbase connection using the 
>> > current thread as the key to a hashtable.  Also, I know that I will 
>> > have to be careful with thread synchronization.
>> >
>> > Thanks,
>> > sean
>> >
>> >
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
>> For additional commands, e-mail: user-help@struts.apache.org
>>
>>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
> For additional commands, e-mail: user-help@struts.apache.org
>
>
> 



---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org


Re: Idea for chain and DB transactions

Posted by atta-ur rehman <at...@gmail.com>.
Craig,

That sounds pretty exciting. Now, how could I, if at all, incorporate
this Filter/Chian functionality in my existing Struts 1.1 app?

ATTA


On Sat, 18 Sep 2004 07:19:45 -0700, Craig McClanahan <cr...@gmail.com> wrote:
> Commons Chain (on which Struts Chain is based) has a design pattern
> built in for the general case were one command in the chain wants to
> allocate resources that will be required for later commands in the
> chain, plus the ability to clean up that resource when the chain
> completes.  See the Javadocs for org.apache.commons.chain.Filter.
> 
> For example, assume you want to allocate a connection from a
> connection pool defined as a JNDI resource (the same principle applies
> to any other sort of resource allocation factory) -- create a Filter
> with the following functionality:
> 
> * In the execute() method, acquire a reference to the data source,
>   acquire a connection, and store it as an attribute in the context.
> 
>   public boolean execute(Context context) throws Exception {
>       InitialContext ic = new InitialContext();
>       DataSource ds = (DataSource)
>         ic.lookup("java:comp/env/jdbc/CustomerDatabase");
>       Connection conn = ds.getConnection();
>       context.put("connection", conn);
>       return false;
>   }
> 
> * In the postprocess() method, call close() on the connection,
>   which returns it to the pool:
> 
>   public boolean postprocess(Context context, Exception exception) {
>     Connection conn = (Connection) context.get("connection");
>     conn.close();
>     return false;
>   }
> 
>   Note that the postprocessing method will be called even if an
> exception was thrown in a
>   subsequently called command.
> 
> In all other commands, the execute() method can simply use the
> allocated resource, without having to care how it got there:
> 
>   public boolean execute(Context context) throws Exception {
>     Connection conn = (Connection) context.get("connection");
>     ... use the connection to perform database transactions ...
>   }
> 
> Using this design, you don't have to worry about external storage of
> the allocated resources -- just store them under a well known
> attribute name in the context object that is passed in to all
> commands.
> 
> Craig
> 
> On Fri, 17 Sep 2004 14:43:57 -0400, Sean Schofield
> 
> 
> <se...@schof.com> wrote:
> > I have a problem and a proposed solution.  I would greatly appreciate any feedback about the proposed solution.
> >
> > Problem:
> > =======
> > I'm currently using a Struts application with a connection pool (using DBCP as supplied by Tomat).  When a database update is needed, the Struts actions will call the facade which will talk to my service layer (currently POJO's which handle business logic.)  My service layer in turn talks to the appropriate DAO.  Each of these DAO's extends from a common abstract class that provides basic functionality including obtaining a connection from the DataSource (via the pool).  A key aspect of my design is that some updates are in distinct areas of the database and so I have different DAO's for each area (ex. one for "workflow" on for "document.")
> >
> > As currently implemented I am unable to take advantage of transactions because the two DAOs will be getting a connection indepently from the pool and they will most likely not obtain the connection each time.  If I could just get the same connection each time, then I could use setAutoCommit(false).
> >
> > Proposed Solution:
> > ==============
> > I'm thinking I could set up a few chains for the various kind of updates.  The chains would be called by the POJO service layer (instead of calling the DAO's directly.)  The first Command in the chain would be to indentify all database updates in the chain as needing transactions.  This would be done through a static method on a new object called TransactionManager.  Basically I would have a hashtable that would maintain connections for the duration of the chain.  The connections would be stored by the current thread (use that as the key to the table.)
> >
> > Then when a command down the line needs a database connection, it would first check to see if there is one already set aside for it to use.  Actually the command would call the DAO and the DAO would check.  The command would also be decorated by a custom wrapper so that if the DAO's try to close the connection, I'll ignore it.  Then when the chain does the post processing in reverse order.  So the last clean up step will be to check for my custom DAOException.  If there is one, then rollback, otherwise commit.  Finally, the connection is removed from the TransactionManager.
> >
> > I think this might be crazy enough to work.  I know we could allways use EJB and get transactions but that might be overkill since the volume is very light (this is custom software for a government agency not ecommerce.)  Please let me know what you think.  A big question I have is about storing and retrieving the datbase connection using the current thread as the key to a hashtable.  Also, I know that I will have to be careful with thread synchronization.
> >
> > Thanks,
> > sean
> >
> >
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
> For additional commands, e-mail: user-help@struts.apache.org
> 
>

---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org


Re: Idea for chain and DB transactions

Posted by Craig McClanahan <cr...@gmail.com>.
Commons Chain (on which Struts Chain is based) has a design pattern
built in for the general case were one command in the chain wants to
allocate resources that will be required for later commands in the
chain, plus the ability to clean up that resource when the chain
completes.  See the Javadocs for org.apache.commons.chain.Filter.

For example, assume you want to allocate a connection from a
connection pool defined as a JNDI resource (the same principle applies
to any other sort of resource allocation factory) -- create a Filter
with the following functionality:

* In the execute() method, acquire a reference to the data source,
  acquire a connection, and store it as an attribute in the context.

  public boolean execute(Context context) throws Exception {
      InitialContext ic = new InitialContext();
      DataSource ds = (DataSource)
        ic.lookup("java:comp/env/jdbc/CustomerDatabase");
      Connection conn = ds.getConnection();
      context.put("connection", conn);
      return false;
  }

* In the postprocess() method, call close() on the connection,
  which returns it to the pool:

  public boolean postprocess(Context context, Exception exception) {
    Connection conn = (Connection) context.get("connection");
    conn.close();
    return false;
  }

  Note that the postprocessing method will be called even if an
exception was thrown in a
  subsequently called command.

In all other commands, the execute() method can simply use the
allocated resource, without having to care how it got there:

  public boolean execute(Context context) throws Exception {
    Connection conn = (Connection) context.get("connection");
    ... use the connection to perform database transactions ...
  }

Using this design, you don't have to worry about external storage of
the allocated resources -- just store them under a well known
attribute name in the context object that is passed in to all
commands.

Craig

On Fri, 17 Sep 2004 14:43:57 -0400, Sean Schofield
<se...@schof.com> wrote:
> I have a problem and a proposed solution.  I would greatly appreciate any feedback about the proposed solution.
> 
> Problem:
> =======
> I'm currently using a Struts application with a connection pool (using DBCP as supplied by Tomat).  When a database update is needed, the Struts actions will call the facade which will talk to my service layer (currently POJO's which handle business logic.)  My service layer in turn talks to the appropriate DAO.  Each of these DAO's extends from a common abstract class that provides basic functionality including obtaining a connection from the DataSource (via the pool).  A key aspect of my design is that some updates are in distinct areas of the database and so I have different DAO's for each area (ex. one for "workflow" on for "document.")
> 
> As currently implemented I am unable to take advantage of transactions because the two DAOs will be getting a connection indepently from the pool and they will most likely not obtain the connection each time.  If I could just get the same connection each time, then I could use setAutoCommit(false).
> 
> Proposed Solution:
> ==============
> I'm thinking I could set up a few chains for the various kind of updates.  The chains would be called by the POJO service layer (instead of calling the DAO's directly.)  The first Command in the chain would be to indentify all database updates in the chain as needing transactions.  This would be done through a static method on a new object called TransactionManager.  Basically I would have a hashtable that would maintain connections for the duration of the chain.  The connections would be stored by the current thread (use that as the key to the table.)
> 
> Then when a command down the line needs a database connection, it would first check to see if there is one already set aside for it to use.  Actually the command would call the DAO and the DAO would check.  The command would also be decorated by a custom wrapper so that if the DAO's try to close the connection, I'll ignore it.  Then when the chain does the post processing in reverse order.  So the last clean up step will be to check for my custom DAOException.  If there is one, then rollback, otherwise commit.  Finally, the connection is removed from the TransactionManager.
> 
> I think this might be crazy enough to work.  I know we could allways use EJB and get transactions but that might be overkill since the volume is very light (this is custom software for a government agency not ecommerce.)  Please let me know what you think.  A big question I have is about storing and retrieving the datbase connection using the current thread as the key to a hashtable.  Also, I know that I will have to be careful with thread synchronization.
> 
> Thanks,
> sean
> 
>

---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org


Re: Idea for chain and DB transactions

Posted by Sean Schofield <se...@schof.com>.
I had thought about this but it involves duplicating each DAO method.  Also 
if I ever wanted to switch to EJB I would have to undo all of the methods 
again.  Its definitely an option though.  I was just hoping for something 
that would involve less changes to my DAO's.

Thanks for the feedback.

sean

----- Original Message ----- 
From: "Erik Weber" <er...@mindspring.com>
To: "Struts Users Mailing List" <us...@struts.apache.org>
Sent: Friday, September 17, 2004 2:49 PM
Subject: Re: Idea for chain and DB transactions


> Overload each existing DAO method with a secondary method that accepts the 
> Connection as a parameter instead of getting it on its own. Then let your 
> service layer object obtain the Connection, set autocommit to false, 
> invoke all the DAO methods you need, passing the customized Connection to 
> each. Then commit and set autocommit back to true in your service layer 
> object.
>
> Erik
>
>
> Sean Schofield wrote:
>
>>I have a problem and a proposed solution.  I would greatly appreciate any 
>>feedback about the proposed solution.
>>
>>Problem:
>>=======
>>I'm currently using a Struts application with a connection pool (using 
>>DBCP as supplied by Tomat).  When a database update is needed, the Struts 
>>actions will call the facade which will talk to my service layer 
>>(currently POJO's which handle business logic.)  My service layer in turn 
>>talks to the appropriate DAO.  Each of these DAO's extends from a common 
>>abstract class that provides basic functionality including obtaining a 
>>connection from the DataSource (via the pool).  A key aspect of my design 
>>is that some updates are in distinct areas of the database and so I have 
>>different DAO's for each area (ex. one for "workflow" on for "document.")
>>As currently implemented I am unable to take advantage of transactions 
>>because the two DAOs will be getting a connection indepently from the pool 
>>and they will most likely not obtain the connection each time.  If I could 
>>just get the same connection each time, then I could use 
>>setAutoCommit(false).
>>
>>Proposed Solution:
>>==============
>>I'm thinking I could set up a few chains for the various kind of updates. 
>>The chains would be called by the POJO service layer (instead of calling 
>>the DAO's directly.)  The first Command in the chain would be to indentify 
>>all database updates in the chain as needing transactions.  This would be 
>>done through a static method on a new object called TransactionManager. 
>>Basically I would have a hashtable that would maintain connections for the 
>>duration of the chain.  The connections would be stored by the current 
>>thread (use that as the key to the table.)
>>Then when a command down the line needs a database connection, it would 
>>first check to see if there is one already set aside for it to use. 
>>Actually the command would call the DAO and the DAO would check.  The 
>>command would also be decorated by a custom wrapper so that if the DAO's 
>>try to close the connection, I'll ignore it.  Then when the chain does the 
>>post processing in reverse order.  So the last clean up step will be to 
>>check for my custom DAOException.  If there is one, then rollback, 
>>otherwise commit.  Finally, the connection is removed from the 
>>TransactionManager.
>>
>>I think this might be crazy enough to work.  I know we could allways use 
>>EJB and get transactions but that might be overkill since the volume is 
>>very light (this is custom software for a government agency not 
>>ecommerce.)  Please let me know what you think.  A big question I have is 
>>about storing and retrieving the datbase connection using the current 
>>thread as the key to a hashtable.  Also, I know that I will have to be 
>>careful with thread synchronization.
>>
>>Thanks,
>>sean
>>
>>
>>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
> For additional commands, e-mail: user-help@struts.apache.org
>
> 



---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org


Re: Idea for chain and DB transactions

Posted by Erik Weber <er...@mindspring.com>.
Overload each existing DAO method with a secondary method that accepts 
the Connection as a parameter instead of getting it on its own. Then let 
your service layer object obtain the Connection, set autocommit to 
false, invoke all the DAO methods you need, passing the customized 
Connection to each. Then commit and set autocommit back to true in your 
service layer object.

Erik


Sean Schofield wrote:

>I have a problem and a proposed solution.  I would greatly appreciate any feedback about the proposed solution.
>
>Problem:
>=======
>I'm currently using a Struts application with a connection pool (using DBCP as supplied by Tomat).  When a database update is needed, the Struts actions will call the facade which will talk to my service layer (currently POJO's which handle business logic.)  My service layer in turn talks to the appropriate DAO.  Each of these DAO's extends from a common abstract class that provides basic functionality including obtaining a connection from the DataSource (via the pool).  A key aspect of my design is that some updates are in distinct areas of the database and so I have different DAO's for each area (ex. one for "workflow" on for "document.")  
>
>As currently implemented I am unable to take advantage of transactions because the two DAOs will be getting a connection indepently from the pool and they will most likely not obtain the connection each time.  If I could just get the same connection each time, then I could use setAutoCommit(false).
>
>Proposed Solution:
>==============
>I'm thinking I could set up a few chains for the various kind of updates.  The chains would be called by the POJO service layer (instead of calling the DAO's directly.)  The first Command in the chain would be to indentify all database updates in the chain as needing transactions.  This would be done through a static method on a new object called TransactionManager.  Basically I would have a hashtable that would maintain connections for the duration of the chain.  The connections would be stored by the current thread (use that as the key to the table.)  
>
>Then when a command down the line needs a database connection, it would first check to see if there is one already set aside for it to use.  Actually the command would call the DAO and the DAO would check.  The command would also be decorated by a custom wrapper so that if the DAO's try to close the connection, I'll ignore it.  Then when the chain does the post processing in reverse order.  So the last clean up step will be to check for my custom DAOException.  If there is one, then rollback, otherwise commit.  Finally, the connection is removed from the TransactionManager.
>
>I think this might be crazy enough to work.  I know we could allways use EJB and get transactions but that might be overkill since the volume is very light (this is custom software for a government agency not ecommerce.)  Please let me know what you think.  A big question I have is about storing and retrieving the datbase connection using the current thread as the key to a hashtable.  Also, I know that I will have to be careful with thread synchronization.
>
>Thanks,
>sean
>
>
>  
>

---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org


Re: Idea for chain and DB transactions

Posted by Sean Schofield <se...@schof.com>.
Robert,

Thanks for the feedback.  I took a look at Spring.  It seems interesting but 
I decided to pass on it right now rather than take the time to get up to 
speed on yet another framework.

I did take a look at ThreadLocal, however, and I think this will be perfect 
for what I need.  In fact I found an article that describes how to use 
ThreadLocal and uses JDBC connections in one of their examples 
(http://www-106.ibm.com/developerworks/java/library/j-threads3.html).

I had hear people mention ThreadLocal before but I never really knew what it 
was about.  Now that I've taken a look at it I'm pretty impressed.  It was 
interesting to learn that the initial implementation of ThreadLocal was very 
similar to what I was proposing here.  (Apparently, It has since evolved to 
be much more efficient than the initial implementation.)

I'm allways glad to check with others before embarking on a solution like 
this.  Often times I am on the right track but the collective experience of 
programmers can usually come up with a superior solution (much like Struts 
vs. my own efforts before discovering Struts.)

Thanks again!

sean



----- Original Message ----- 
From: "Robert Taylor" <rt...@mulework.com>
To: "Struts Users Mailing List" <us...@struts.apache.org>
Sent: Friday, September 17, 2004 3:17 PM
Subject: RE: Idea for chain and DB transactions


> Sean, have you looked at Spring? It uses AOP and you can set up 
> transactions declaratively.
>
> I'm just starting to investigate using Spring and I'm really impressed.
> Like you I had a requirement to demarcate transactions at a high level so 
> that
> all business objects within the transaction were subject to the same 
> transaction
> semantics unless a business object explicitely needed to be isolated.
>
> I ended up creating a Transaction framework of sorts which uses 
> ThreadLocal to
> propogate the Connection to my DAO's. All DAO's that need to be included 
> in a
> transaction had to subclass a TransactionalDAO which "knew" how to access 
> the
> current TransactionContext from ThreadLocal.
>
> It has worked for a couple years now, but its not that clean or elegant.
>
> That's why I was so excited to read about Spring and IoC.  It does all 
> that stuff
> for you.
>
> robert
>
>> -----Original Message-----
>> From: Sean Schofield [mailto:sean_schofield@schof.com]
>> Sent: Friday, September 17, 2004 2:44 PM
>> To: user@struts.apache.org
>> Subject: Idea for chain and DB transactions
>>
>>
>> I have a problem and a proposed solution.  I would greatly appreciate any 
>> feedback about the proposed solution.
>>
>> Problem:
>> =======
>> I'm currently using a Struts application with a connection pool (using 
>> DBCP as supplied by Tomat).  When a database
>> update is needed, the Struts actions will call the facade which will talk 
>> to my service layer (currently POJO's which
>> handle business logic.)  My service layer in turn talks to the 
>> appropriate DAO.  Each of these DAO's extends from a
>> common abstract class that provides basic functionality including 
>> obtaining a connection from the DataSource (via the
>> pool).  A key aspect of my design is that some updates are in distinct 
>> areas of the database and so I have different
>> DAO's for each area (ex. one for "workflow" on for "document.")
>>
>> As currently implemented I am unable to take advantage of transactions 
>> because the two DAOs will be getting a connection
>> indepently from the pool and they will most likely not obtain the 
>> connection each time.  If I could just get the same
>> connection each time, then I could use setAutoCommit(false).
>>
>> Proposed Solution:
>> ==============
>> I'm thinking I could set up a few chains for the various kind of updates. 
>> The chains would be called by the POJO service
>> layer (instead of calling the DAO's directly.)  The first Command in the 
>> chain would be to indentify all database updates
>> in the chain as needing transactions.  This would be done through a 
>> static method on a new object called
>> TransactionManager.  Basically I would have a hashtable that would 
>> maintain connections for the duration of the chain.
>> The connections would be stored by the current thread (use that as the 
>> key to the table.)
>>
>> Then when a command down the line needs a database connection, it would 
>> first check to see if there is one already set
>> aside for it to use.  Actually the command would call the DAO and the DAO 
>> would check.  The command would also be
>> decorated by a custom wrapper so that if the DAO's try to close the 
>> connection, I'll ignore it.  Then when the chain does
>> the post processing in reverse order.  So the last clean up step will be 
>> to check for my custom DAOException.  If there
>> is one, then rollback, otherwise commit.  Finally, the connection is 
>> removed from the TransactionManager.
>>
>> I think this might be crazy enough to work.  I know we could allways use 
>> EJB and get transactions but that might be
>> overkill since the volume is very light (this is custom software for a 
>> government agency not ecommerce.)  Please let me
>> know what you think.  A big question I have is about storing and 
>> retrieving the datbase connection using the current
>> thread as the key to a hashtable.  Also, I know that I will have to be 
>> careful with thread synchronization.
>>
>> Thanks,
>> sean
>>
>>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
> For additional commands, e-mail: user-help@struts.apache.org
>
>
> 



---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org


RE: Idea for chain and DB transactions

Posted by Robert Taylor <rt...@mulework.com>.
Sean, have you looked at Spring? It uses AOP and you can set up transactions declaratively.

I'm just starting to investigate using Spring and I'm really impressed. 
Like you I had a requirement to demarcate transactions at a high level so that
all business objects within the transaction were subject to the same transaction
semantics unless a business object explicitely needed to be isolated. 

I ended up creating a Transaction framework of sorts which uses ThreadLocal to 
propogate the Connection to my DAO's. All DAO's that need to be included in a 
transaction had to subclass a TransactionalDAO which "knew" how to access the
current TransactionContext from ThreadLocal.

It has worked for a couple years now, but its not that clean or elegant. 

That's why I was so excited to read about Spring and IoC.  It does all that stuff
for you.

robert

> -----Original Message-----
> From: Sean Schofield [mailto:sean_schofield@schof.com]
> Sent: Friday, September 17, 2004 2:44 PM
> To: user@struts.apache.org
> Subject: Idea for chain and DB transactions
> 
> 
> I have a problem and a proposed solution.  I would greatly appreciate any feedback about the proposed solution.
> 
> Problem:
> =======
> I'm currently using a Struts application with a connection pool (using DBCP as supplied by Tomat).  When a database 
> update is needed, the Struts actions will call the facade which will talk to my service layer (currently POJO's which 
> handle business logic.)  My service layer in turn talks to the appropriate DAO.  Each of these DAO's extends from a 
> common abstract class that provides basic functionality including obtaining a connection from the DataSource (via the 
> pool).  A key aspect of my design is that some updates are in distinct areas of the database and so I have different 
> DAO's for each area (ex. one for "workflow" on for "document.")  
> 
> As currently implemented I am unable to take advantage of transactions because the two DAOs will be getting a connection 
> indepently from the pool and they will most likely not obtain the connection each time.  If I could just get the same 
> connection each time, then I could use setAutoCommit(false).
> 
> Proposed Solution:
> ==============
> I'm thinking I could set up a few chains for the various kind of updates.  The chains would be called by the POJO service 
> layer (instead of calling the DAO's directly.)  The first Command in the chain would be to indentify all database updates 
> in the chain as needing transactions.  This would be done through a static method on a new object called 
> TransactionManager.  Basically I would have a hashtable that would maintain connections for the duration of the chain.  
> The connections would be stored by the current thread (use that as the key to the table.)  
> 
> Then when a command down the line needs a database connection, it would first check to see if there is one already set 
> aside for it to use.  Actually the command would call the DAO and the DAO would check.  The command would also be 
> decorated by a custom wrapper so that if the DAO's try to close the connection, I'll ignore it.  Then when the chain does 
> the post processing in reverse order.  So the last clean up step will be to check for my custom DAOException.  If there 
> is one, then rollback, otherwise commit.  Finally, the connection is removed from the TransactionManager.
> 
> I think this might be crazy enough to work.  I know we could allways use EJB and get transactions but that might be 
> overkill since the volume is very light (this is custom software for a government agency not ecommerce.)  Please let me 
> know what you think.  A big question I have is about storing and retrieving the datbase connection using the current 
> thread as the key to a hashtable.  Also, I know that I will have to be careful with thread synchronization.
> 
> Thanks,
> sean
> 
> 

---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org