I replied from wrong email, please excuse me if this reaches the list twice.

On Tue, May 6, 2014 at 8:06 PM, tetsuo <[email protected]> wrote:
> Since it's the same request, isn't (or couldn't be) the db connection the
> same in size() and iterator() calls? If you created the temporary table in
> one, isn't it still available to the other (so you could avoid recreating
> it)?
Well, the connection is being managed by spring transactional resource
management classes. A transaction is demarcated with
@Transactional(readOnly=true) on a particular method. All
transactional resources are bound to thread during transaction
execution and released when transaction finishes. One transactional
resource is of course a connection. I have extended this framework to
register temporary table names which are being automatically deleted
on transaction finish.

Each time you invoke a transactional method you perform following steps:
- acquire a connection from the pool
- bind connection to thread making all subsequent queries use same connection
- start transaction
- do some work
- finish transaction (of course for read only there is nothing to be done)
- release transactional resources
- unbind connection from thread
- release connection to the pool.

using spring framework without spring managed transactions means you
end up using different connection for EVERY sql query.

My IDataProviders usually wrap spring bean with
@Transactional(readOnly=true) methods.

Unfortunatelly two method calls: size() and iterator() mean two
different transaction and two different connections. I am unable to
wrap any single point of entry with @Transactional - that probably
would have to be some generic Wicket method call. I cannot bind a
connection to current request thread preemptively because that would
mean a huge resource hog - I would have to obtain a connection from
pool for every request being made.

Temporary tables have connection scope so not deleting the table on
connection release means polluting the database server with lots of
temporary tables as long as connection stays in pool (which could be
indefinite).
The temporary tables would be probably stale all the time - any
ongoing transaction may probably alter what the temporary table should
contain.

Anyway any approach still feels like a hack and not resolving the
problem at source.



A single point of entry in IDataProvider:
- allows the user to manage resources more efficiently.
- gives user the option to resign from providing size() information -
do you really go from 1st to 15th page that often or do you usually
click "next results"?
- gives user the option to provide "has more results" information
without providing actual dataset size.

Having a single point of entry IDataSource means also you can do:

new IDataProviderSingleEntry<T( oldDataProvider ) {
  public Page<T> getPage( long first, long count ) {
      return new PageImpl<T>(
         oldDataProvider.interator( first, count ), oldDataProvider.size() );
  }
}

This trivial decorator means IDataProviderSingleEntry and
IDataProvider may even coexist in wicket-core and wicket-extensions.
Some variation of this approach is actually used by inmethod-grid.
Maybe we could unify the way all pageables access resources.


-- 
Leszek Gawron

Reply via email to