Implement statement timeout support for PostgreSQL

This commit is contained in:
Heng Sin Low 2011-02-07 10:19:22 +08:00
parent 0ed2e11bd0
commit ce2d57585f
1 changed files with 147 additions and 16 deletions

View File

@ -1011,19 +1011,56 @@ public final class DB
CPreparedStatement cs = ProxyFactory.newCPreparedStatement(ResultSet.TYPE_FORWARD_ONLY, CPreparedStatement cs = ProxyFactory.newCPreparedStatement(ResultSet.TYPE_FORWARD_ONLY,
ResultSet.CONCUR_UPDATABLE, sql, trxName); // converted in call ResultSet.CONCUR_UPDATABLE, sql, trxName); // converted in call
boolean autoCommit = false;
int currentTimeout = 0;
try try
{ {
setParameters(cs, params); setParameters(cs, params);
autoCommit = cs.getConnection().getAutoCommit();
//set timeout
if (timeOut > 0) if (timeOut > 0)
cs.setQueryTimeout(timeOut); {
if (DB.isPostgreSQL())
{
try
{
Connection conn = cs.getConnection();
if (autoCommit)
{
conn.setAutoCommit(false);
}
else
{
ResultSet rs = null;
try
{
rs = conn.createStatement().executeQuery("select current_setting('statement_timeout')");
if (rs.next())
currentTimeout = rs.getInt(1);
}
finally
{
DB.close(rs);
}
}
Statement timeoutStatement = conn.createStatement();
timeoutStatement.execute("SET LOCAL statement_timeout TO " + ( timeOut * 1000 ));
if (log.isLoggable(Level.FINEST))
{
log.finest("Set statement timeout to " + timeOut);
}
} catch (SQLException e) {}
}
else
{
cs.setQueryTimeout(timeOut);
}
}
no = cs.executeUpdate(); no = cs.executeUpdate();
// No Transaction - Commit // No Transaction - Commit
if (trxName == null) if (trxName == null)
{ {
cs.commit(); // Local commit cs.commit(); // Local commit
// Connection conn = cs.getConnection();
// if (conn != null && !conn.getAutoCommit()) // is null for remote
// conn.commit();
} }
} }
catch (Exception e) catch (Exception e)
@ -1040,15 +1077,40 @@ public final class DB
} }
finally finally
{ {
if (DB.isPostgreSQL() && timeOut > 0)
{
try
{
if (autoCommit)
{
cs.getConnection().setAutoCommit(true);
}
else
{
if (currentTimeout > 0)
{
Statement timeoutStatement = cs.getConnection().createStatement();
timeoutStatement.execute("SET LOCAL statement_timeout TO " + ( currentTimeout * 1000 ));
if (log.isLoggable(Level.FINEST))
{
log.finest("Reset statement timeout to " + currentTimeout);
}
}
else
{
Statement timeoutStatement = cs.getConnection().createStatement();
timeoutStatement.execute("SET LOCAL statement_timeout TO Default");
if (log.isLoggable(Level.FINEST))
{
log.finest("Reset statement timeout to default");
}
}
}
}
catch (SQLException e) {}
}
// Always close cursor // Always close cursor
try close(cs);
{
cs.close();
}
catch (SQLException e2)
{
log.log(Level.SEVERE, "Cannot close statement");
}
} }
return no; return no;
} // executeUpdate } // executeUpdate
@ -1085,11 +1147,50 @@ public final class DB
CPreparedStatement cs = ProxyFactory.newCPreparedStatement(ResultSet.TYPE_FORWARD_ONLY, CPreparedStatement cs = ProxyFactory.newCPreparedStatement(ResultSet.TYPE_FORWARD_ONLY,
ResultSet.CONCUR_UPDATABLE, sql, trxName); // converted in call ResultSet.CONCUR_UPDATABLE, sql, trxName); // converted in call
boolean autoCommit = false;
int currentTimeout = 0;
try try
{ {
autoCommit = cs.getConnection().getAutoCommit();
setParameters(cs, params); setParameters(cs, params);
if (timeOut > 0) if (timeOut > 0)
cs.setQueryTimeout(timeOut); {
if (DB.isPostgreSQL())
{
try
{
Connection conn = cs.getConnection();
if (autoCommit)
{
conn.setAutoCommit(false);
}
else
{
ResultSet rs = null;
try
{
rs = conn.createStatement().executeQuery("select current_setting('statement_timeout')");
if (rs.next())
currentTimeout = rs.getInt(1);
}
finally
{
DB.close(rs);
}
}
Statement timeoutStatement = conn.createStatement();
timeoutStatement.execute("SET LOCAL statement_timeout TO " + ( timeOut * 1000 ));
if (log.isLoggable(Level.FINEST))
{
log.finest("Set statement timeout to " + timeOut);
}
} catch (SQLException e) {}
}
else
{
cs.setQueryTimeout(timeOut);
}
}
no = cs.executeUpdate(); no = cs.executeUpdate();
// No Transaction - Commit // No Transaction - Commit
if (trxName == null) if (trxName == null)
@ -1103,6 +1204,38 @@ public final class DB
} }
finally finally
{ {
if (DB.isPostgreSQL() && timeOut > 0)
{
try {
if (autoCommit)
{
cs.getConnection().setAutoCommit(true);
}
else
{
if (currentTimeout > 0)
{
Statement timeoutStatement = cs.getConnection().createStatement();
timeoutStatement.execute("SET LOCAL statement_timeout TO " + ( currentTimeout * 1000 ));
if (log.isLoggable(Level.FINEST))
{
log.finest("Reset statement timeout to " + currentTimeout);
}
}
else
{
Statement timeoutStatement = cs.getConnection().createStatement();
timeoutStatement.execute("SET LOCAL statement_timeout TO Default");
if (log.isLoggable(Level.FINEST))
{
log.finest("Reset statement timeout to default");
}
}
}
} catch (SQLException e) {
}
}
DB.close(cs); DB.close(cs);
} }
return no; return no;
@ -1885,10 +2018,8 @@ public final class DB
public static void printWarning (String comment, SQLWarning warning) public static void printWarning (String comment, SQLWarning warning)
{ {
if (comment == null || warning == null || comment.length() == 0) if (comment == null || warning == null || comment.length() == 0)
throw new IllegalArgumentException("Required parameter missing");
log.warning(comment);
if (warning == null)
return; return;
log.warning(comment);
// //
SQLWarning warn = warning; SQLWarning warn = warning;
while (warn != null) while (warn != null)