Subject RE: [Firebird-Java] Re: A suggestion
Author Robert DiFalco
No, I cache with autocommit OFF. Basically, I have code like this. Let
me know if you see anything garingly wrong:

final class PooledConnection extends LinkList.Node implements Connection
{
/* Uniquely identified each connection for quick in-use map lookups
*/
private static int sm_count = 0;

/** The integer identity of this connection */
protected int m_identity = ++sm_count;

/** The time at which this connection was created */
protected long m_stamp = System.currentTimeMillis();

/** A map of cached statements */
private final Map m_statementCache =
new LinkedHashMap( STATEMENT_CACHE_SIZE, 0.75f, true )
{
protected boolean removeEldestEntry( final Map.Entry eldest
)
{
if ( size() <= STATEMENT_CACHE_SIZE )
{
return false;
}
else
{
final CachedPreparedStatement ps =
(CachedPreparedStatement)eldest.getValue();

if ( ps.isActive() )
{
return false;
}

try
{
ps.reallyClose();
}
catch ( SQLException e )
{
e.printStackTrace();
}

return true;
}
}
};

...

public PreparedStatement prepareStatement( final String sql )
throws SQLException
{
final Object o = m_statementCache.get( sql );

if ( o != null )
{
return (PreparedStatement)o;
}
else
{
final CachedPreparedStatement ps =
new CachedPreparedStatement( sql, m_connection );

m_statementCache.put( sql, ps );

return ps;
}
}

...

public void close() throws SQLException
{
// close cached statements
for ( final Iterator it =
m_statementCache.values().iterator(); it.hasNext(); )
{
final CachedPreparedStatement st =
(CachedPreparedStatement)it.next();

try
{
// really close the statement
st.reallyClose();
}
catch ( Exception e )
{
e.printStackTrace();
}
}

// Clear references from the statement cache
m_statementCache.clear();

// close the real connection
m_connection.close();
}
}

/**
* A wrapper for prepared statement for caching.
*/
class CachedPreparedStatement implements PreparedStatement
{
/** We change the behavior of close to just flip this switch. */
private boolean m_active = true;

/** The string used to create this statement, usefull for debugging.
*/
private String m_sql;

/** The real statement we are delegating to */
private PreparedStatement m_statement;

public CachedPreparedStatement( final String sql, final Connection
con ) throws SQLException
{
m_sql = sql;
m_statement = con.prepareStatement( sql );
}

...

public void close() throws SQLException
{
clearParameters();

try
{
clearWarnings();
}
catch ( SQLException e )
{
e.printStackTrace();
}

// mark it as no longer active
m_active = false;
}

public void reallyClose() throws SQLException
{
m_active = false;
m_statement.close();
}

...
}

Basically something like that. The default settings for the max
connections is 4 and each connection has a max-size statement cache of
8.



-----Original Message-----
From: Roman Rokytskyy [mailto:rrokytskyy@...]
Sent: Wednesday, October 22, 2003 1:22 PM
To: Firebird-Java@yahoogroups.com
Subject: [Firebird-Java] Re: A suggestion


Robert,

> If you add these to FBBlobField, that should do it. Until then, if
> you use Blob's with much data, I would NOT cache prepared
> statements.

Do you cache prepared statement in auto-commit mode? Because large
strings (max. length is 32k though) and cached blobs (auto-commit
case, in non-autocommit case we store only blob ID) seems to be the
only thing worth freeing (other data types consume less memory than
FBField object itself).

I will check where it would be better to release objects for garbage
collection.

Best regards,
Roman


Yahoo! Groups Sponsor
ADVERTISEMENT




To unsubscribe from this group, send an email to:
Firebird-Java-unsubscribe@yahoogroups.com



Your use of Yahoo! Groups is subject to the Yahoo! Terms of Service.