You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by re...@apache.org on 2015/09/17 13:00:20 UTC

svn commit: r1703568 - /jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBDocumentStorePerformanceTest.java

Author: reschke
Date: Thu Sep 17 11:00:17 2015
New Revision: 1703568

URL: http://svn.apache.org/r1703568
Log:
OAK-3413: RDBDocumentStorePerformanceTest - fix leak of PreparedStatements

Modified:
    jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBDocumentStorePerformanceTest.java

Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBDocumentStorePerformanceTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBDocumentStorePerformanceTest.java?rev=1703568&r1=1703567&r2=1703568&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBDocumentStorePerformanceTest.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBDocumentStorePerformanceTest.java Thu Sep 17 11:00:17 2015
@@ -31,7 +31,6 @@ import java.util.UUID;
 import org.apache.jackrabbit.oak.plugins.document.AbstractDocumentStoreTest;
 import org.apache.jackrabbit.oak.plugins.document.DocumentStoreException;
 import org.apache.jackrabbit.oak.plugins.document.DocumentStoreFixture;
-import org.apache.jackrabbit.oak.plugins.document.DocumentStorePerformanceTest;
 import org.junit.Test;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -40,17 +39,19 @@ import org.slf4j.LoggerFactory;
  * Tests measuring the performance of various {@link RDBDocumentStore}
  * operations.
  * <p>
- * These tests are disabled by default due to their long running time. On the command line
- * specify {@code -DRDBDocumentStorePerformanceTest=true} to enable them.
+ * These tests are disabled by default due to their long running time. On the
+ * command line specify {@code -DRDBDocumentStorePerformanceTest=true} to enable
+ * them.
  */
 public class RDBDocumentStorePerformanceTest extends AbstractDocumentStoreTest {
 
     private static final Logger LOG = LoggerFactory.getLogger(RDBDocumentStorePerformanceTest.class);
-    private static final boolean ENABLED = Boolean.getBoolean(DocumentStorePerformanceTest.class.getSimpleName());
+    private static final boolean ENABLED = Boolean.getBoolean(RDBDocumentStorePerformanceTest.class.getSimpleName());
 
     public RDBDocumentStorePerformanceTest(DocumentStoreFixture dsf) {
         super(dsf);
         assumeTrue(ENABLED);
+        assumeTrue(super.rdbDataSource != null);
     }
 
     @Test
@@ -79,218 +80,195 @@ public class RDBDocumentStorePerformance
     }
 
     private void internalTestPerfUpdateLimit(String name, String desc, int mode) throws SQLException, UnsupportedEncodingException {
-        if (super.rdbDataSource != null) {
-            String key = name;
-            Connection connection = null;
-            String table = DocumentStoreFixture.TABLEPREFIX + "NODES";
-
-            // create test node
+        String key = name;
+        Connection connection = null;
+        String table = DocumentStoreFixture.TABLEPREFIX + "NODES";
+
+        // create test node
+        try {
+            connection = super.rdbDataSource.getConnection();
+            connection.setAutoCommit(false);
+            // we use the same pool as the document store, and the
+            // connection might have been returned in read-only mode
+            connection.setReadOnly(false);
+            PreparedStatement stmt = connection.prepareStatement("insert into " + table + " (ID, MODCOUNT, DATA) values (?, ?, ?)");
             try {
-                connection = super.rdbDataSource.getConnection();
-                connection.setAutoCommit(false);
-                // we use the same pool as the document store, and the
-                // connection might have been returned in read-only mode
-                connection.setReadOnly(false);
-                PreparedStatement stmt = connection.prepareStatement("insert into " + table
-                        + " (ID, MODCOUNT, DATA) values (?, ?, ?)");
-                try {
-                    setIdInStatement(stmt, 1, key);
-                    stmt.setLong(2, 0);
-                    stmt.setString(3, "X");
-                    stmt.executeUpdate();
-                    connection.commit();
-                } finally {
-                    stmt.close();
-                }
-            } catch (SQLException ex) {
-                // ignored
-                // ex.printStackTrace();
+                setIdInStatement(stmt, 1, key);
+                stmt.setLong(2, 0);
+                stmt.setString(3, "X");
+                stmt.executeUpdate();
+                connection.commit();
             } finally {
-                if (connection != null) {
-                    try {
-                        connection.close();
-                    } catch (SQLException e) {
-                        // ignored
-                    }
-                }
+                stmt = close(stmt);
             }
+        } catch (SQLException ex) {
+            // ignored
+            // ex.printStackTrace();
+        } finally {
+            connection = close(connection);
+        }
 
-            removeMe.add(key);
-            StringBuffer expect = new StringBuffer("X");
+        removeMe.add(key);
+        StringBuffer expect = new StringBuffer("X");
 
-            String appendString = generateString(512, true);
+        String appendString = generateString(512, true);
 
-            long duration = 1000;
-            long end = System.currentTimeMillis() + duration;
-            long cnt = 0;
-            byte bdata[] = new byte[65536];
-            String sdata = appendString;
-            boolean needsConcat = super.dsname.contains("MySQL");
-            boolean needsSQLStringConcat = super.dsname.contains("MSSql");
-            int dataInChars = ((super.dsname.contains("Oracle") || (super.dsname.contains("MSSql"))) ? 4000 : 16384);
-            int dataInBytes = dataInChars / 3;
+        long duration = 1000;
+        long end = System.currentTimeMillis() + duration;
+        long cnt = 0;
+        byte bdata[] = new byte[65536];
+        String sdata = appendString;
+        boolean needsConcat = super.dsname.contains("MySQL");
+        boolean needsSQLStringConcat = super.dsname.contains("MSSql");
+        int dataInChars = ((super.dsname.contains("Oracle") || (super.dsname.contains("MSSql"))) ? 4000 : 16384);
+        int dataInBytes = dataInChars / 3;
 
-            while (System.currentTimeMillis() < end) {
+        while (System.currentTimeMillis() < end) {
 
-                try {
-                    connection = super.rdbDataSource.getConnection();
-                    connection.setAutoCommit(false);
+            try {
+                connection = super.rdbDataSource.getConnection();
+                connection.setAutoCommit(false);
 
-                    if (mode == 0) {
-                        PreparedStatement stmt = connection.prepareStatement("update " + table + " set MODCOUNT = ? where ID = ?");
-                        try {
-                            stmt.setLong(1, cnt);
-                            setIdInStatement(stmt, 2, key);
-                            assertEquals(1, stmt.executeUpdate());
-                            connection.commit();
-                        } finally {
-                            stmt.close();
-                        }
-                    } else if (mode == 1) {
-                        PreparedStatement stmt = connection.prepareStatement("update " + table
-                                + " set MODCOUNT = ?, DATA = ? where ID = ?");
-                        try {
-                            stmt.setLong(1, cnt);
-                            stmt.setString(2, "JSON data " + UUID.randomUUID());
-                            setIdInStatement(stmt, 3, key);
-                            assertEquals(1, stmt.executeUpdate());
-                            connection.commit();
-                        } finally {
-                            stmt.close();
-                        }
-                    } else if (mode == 2) {
-                        PreparedStatement stmt = connection.prepareStatement("update " + table
-                                + " set MODCOUNT = ?, DATA = ?, BDATA = ? where ID = ?");
-                        try {
-                            stmt.setLong(1, cnt);
-                            stmt.setString(2, "JSON data " + UUID.randomUUID());
-                            bdata[(int) cnt % bdata.length] = (byte) (cnt & 0xff);
-                            stmt.setString(2, "JSON data " + UUID.randomUUID());
-                            stmt.setBytes(3, bdata);
-                            setIdInStatement(stmt, 4, key);
-                            assertEquals(1, stmt.executeUpdate());
-                            connection.commit();
-                        } finally {
-                            stmt.close();
-                        }
-                    } else if (mode == 3) {
-                        String t = "update " + table + " ";
+                if (mode == 0) {
+                    PreparedStatement stmt = connection.prepareStatement("update " + table + " set MODCOUNT = ? where ID = ?");
+                    try {
+                        stmt.setLong(1, cnt);
+                        setIdInStatement(stmt, 2, key);
+                        assertEquals(1, stmt.executeUpdate());
+                        connection.commit();
+                    } finally {
+                        stmt = close(stmt);
+                    }
+                } else if (mode == 1) {
+                    PreparedStatement stmt = connection
+                            .prepareStatement("update " + table + " set MODCOUNT = ?, DATA = ? where ID = ?");
+                    try {
+                        stmt.setLong(1, cnt);
+                        stmt.setString(2, "JSON data " + UUID.randomUUID());
+                        setIdInStatement(stmt, 3, key);
+                        assertEquals(1, stmt.executeUpdate());
+                        connection.commit();
+                    } finally {
+                        stmt = close(stmt);
+                    }
+                } else if (mode == 2) {
+                    PreparedStatement stmt = connection
+                            .prepareStatement("update " + table + " set MODCOUNT = ?, DATA = ?, BDATA = ? where ID = ?");
+                    try {
+                        stmt.setLong(1, cnt);
+                        stmt.setString(2, "JSON data " + UUID.randomUUID());
+                        bdata[(int) cnt % bdata.length] = (byte) (cnt & 0xff);
+                        stmt.setString(2, "JSON data " + UUID.randomUUID());
+                        stmt.setBytes(3, bdata);
+                        setIdInStatement(stmt, 4, key);
+                        assertEquals(1, stmt.executeUpdate());
+                        connection.commit();
+                    } finally {
+                        stmt = close(stmt);
+                    }
+                } else if (mode == 3) {
+                    String t = "update " + table + " ";
 
-                        t += "set DATA = ";
-                        if (needsConcat) {
-                            t += "CONCAT(DATA, ?) ";
-                        } else if (needsSQLStringConcat) {
-                            t += "CASE WHEN LEN(DATA) <= " + (dataInChars - appendString.length())
-                                    + " THEN (DATA + CAST(? AS nvarchar(" + 4000
-                                    + "))) ELSE (DATA + CAST(DATA AS nvarchar(max))) END";
-                        } else {
-                            t += "DATA || CAST(? as varchar(" + dataInChars + "))";
-                        }
+                    t += "set DATA = ";
+                    if (needsConcat) {
+                        t += "CONCAT(DATA, ?) ";
+                    } else if (needsSQLStringConcat) {
+                        t += "CASE WHEN LEN(DATA) <= " + (dataInChars - appendString.length()) + " THEN (DATA + CAST(? AS nvarchar("
+                                + 4000 + "))) ELSE (DATA + CAST(DATA AS nvarchar(max))) END";
+                    } else {
+                        t += "DATA || CAST(? as varchar(" + dataInChars + "))";
+                    }
 
-                        t += " where ID = ?";
+                    t += " where ID = ?";
 
-                        PreparedStatement stmt = connection.prepareStatement(t);
-                        try {
-                            stmt.setString(1, appendString);
+                    PreparedStatement stmt = connection.prepareStatement(t);
+                    try {
+                        stmt.setString(1, appendString);
+                        setIdInStatement(stmt, 2, key);
+                        assertEquals(1, stmt.executeUpdate());
+                        connection.commit();
+                        expect.append(appendString);
+                    } catch (SQLException ex) {
+                        // ex.printStackTrace();
+                        String state = ex.getSQLState();
+                        if ("22001".equals(state)
+                                /* everybody */ || ("72000".equals(state) && 1489 == ex.getErrorCode()) /* Oracle */) {
+                            // overflow
+                            stmt = close(stmt);
+                            connection.rollback();
+                            stmt = connection
+                                    .prepareStatement("update " + table + " set MODCOUNT = MODCOUNT + 1, DATA = ? where ID = ?");
+                            stmt.setString(1, "X");
                             setIdInStatement(stmt, 2, key);
                             assertEquals(1, stmt.executeUpdate());
                             connection.commit();
-                            expect.append(appendString);
-                        } catch (SQLException ex) {
+                            expect = new StringBuffer("X");
+                        } else {
                             // ex.printStackTrace();
-                            String state = ex.getSQLState();
-                            if ("22001".equals(state) /* everybody */|| ("72000".equals(state) && 1489 == ex.getErrorCode()) /* Oracle */) {
-                                // overflow
-                                connection.rollback();
-                                stmt = connection.prepareStatement("update " + table
-                                        + " set MODCOUNT = MODCOUNT + 1, DATA = ? where ID = ?");
-                                stmt.setString(1, "X");
-                                setIdInStatement(stmt, 2, key);
-                                assertEquals(1, stmt.executeUpdate());
-                                connection.commit();
-                                expect = new StringBuffer("X");
-                            } else {
-                                // ex.printStackTrace();
-                                throw (ex);
-                            }
-                        } finally {
-                            stmt.close();
+                            throw (ex);
                         }
-                    } else if (mode == 4) {
-                        PreparedStatement stmt = connection
-                                .prepareStatement("update "
-                                        + table
-                                        + " set MODIFIED = ?, HASBINARY = ?, MODCOUNT = ?, CMODCOUNT = ?, DSIZE = ?, DATA = ?, BDATA = ? where ID = ?");
-                        try {
-                            int si = 1;
-                            stmt.setObject(si++, System.currentTimeMillis() / 5, Types.BIGINT);
-                            stmt.setObject(si++, 0, Types.SMALLINT);
-                            stmt.setObject(si++, cnt, Types.BIGINT);
-                            stmt.setObject(si++, null, Types.BIGINT);
-                            stmt.setObject(si++, sdata.length(), Types.BIGINT);
-
-                            if (sdata.length() < dataInBytes) {
-                                stmt.setString(si++, sdata);
-                                stmt.setBinaryStream(si++, null, 0);
-                            } else {
-                                stmt.setString(si++, "null");
-                                stmt.setBytes(si++, sdata.getBytes("UTF-8"));
-                            }
-                            setIdInStatement(stmt, si++, key);
-                            assertEquals(1, stmt.executeUpdate());
-                            connection.commit();
-                            sdata += appendString;
-                        } finally {
-                            stmt.close();
-                        }
-
+                    } finally {
+                        stmt = close(stmt);
                     }
-                } catch (SQLException ex) {
-                    LOG.error(ex.getMessage() + " " + ex.getSQLState() + " " + ex.getErrorCode(), ex);
-                } finally {
-                    if (connection != null) {
-                        try {
-                            connection.close();
-                        } catch (SQLException e) {
-                            // ignored
+                } else if (mode == 4) {
+                    PreparedStatement stmt = connection.prepareStatement("update " + table
+                            + " set MODIFIED = ?, HASBINARY = ?, MODCOUNT = ?, CMODCOUNT = ?, DSIZE = ?, DATA = ?, BDATA = ? where ID = ?");
+                    try {
+                        int si = 1;
+                        stmt.setObject(si++, System.currentTimeMillis() / 5, Types.BIGINT);
+                        stmt.setObject(si++, 0, Types.SMALLINT);
+                        stmt.setObject(si++, cnt, Types.BIGINT);
+                        stmt.setObject(si++, null, Types.BIGINT);
+                        stmt.setObject(si++, sdata.length(), Types.BIGINT);
+
+                        if (sdata.length() < dataInBytes) {
+                            stmt.setString(si++, sdata);
+                            stmt.setBinaryStream(si++, null, 0);
+                        } else {
+                            stmt.setString(si++, "null");
+                            stmt.setBytes(si++, sdata.getBytes("UTF-8"));
                         }
+                        setIdInStatement(stmt, si++, key);
+                        assertEquals(1, stmt.executeUpdate());
+                        connection.commit();
+                        sdata += appendString;
+                    } finally {
+                        stmt = close(stmt);
                     }
-                }
 
-                cnt += 1;
+                }
+            } catch (SQLException ex) {
+                LOG.error(ex.getMessage() + " " + ex.getSQLState() + " " + ex.getErrorCode(), ex);
+            } finally {
+                connection = close(connection);
             }
 
-            // check persisted values
-            if (mode == 3) {
+            cnt += 1;
+        }
+
+        // check persisted values
+        if (mode == 3) {
+            try {
+                connection = super.rdbDataSource.getConnection();
+                connection.setAutoCommit(false);
+                PreparedStatement stmt = connection.prepareStatement("select DATA, MODCOUNT from " + table + " where ID = ?");
                 try {
-                    connection = super.rdbDataSource.getConnection();
-                    connection.setAutoCommit(false);
-                    PreparedStatement stmt = connection.prepareStatement("select DATA, MODCOUNT from " + table + " where ID = ?");
-                    try {
-                        setIdInStatement(stmt, 1, key);
-                        ResultSet rs = stmt.executeQuery();
-                        assertTrue("test record " + key + " not found in " + super.dsname, rs.next());
-                        String got = rs.getString(1);
-                        long modc = rs.getLong(2);
-                        LOG.info("column reset " + modc + " times");
-                        assertEquals(expect.toString(), got);
-                    } finally {
-                        stmt.close();
-                    }
+                    setIdInStatement(stmt, 1, key);
+                    ResultSet rs = stmt.executeQuery();
+                    assertTrue("test record " + key + " not found in " + super.dsname, rs.next());
+                    String got = rs.getString(1);
+                    long modc = rs.getLong(2);
+                    LOG.info("column reset " + modc + " times");
+                    assertEquals(expect.toString(), got);
                 } finally {
-                    if (connection != null) {
-                        try {
-                            connection.close();
-                        } catch (SQLException e) {
-                            // ignored
-                        }
-                    }
+                    stmt = close(stmt);
                 }
+            } finally {
+                connection = close(connection);
             }
-
-            LOG.info(desc + " for " + super.dsname + " was " + cnt + " in " + duration + "ms (" + (cnt / (duration / 1000f))
-                    + "/s)");
         }
+
+        LOG.info(desc + " for " + super.dsname + " was " + cnt + " in " + duration + "ms (" + (cnt / (duration / 1000f)) + "/s)");
     }
 
     private void setIdInStatement(PreparedStatement stmt, int idx, String id) throws SQLException {
@@ -306,4 +284,26 @@ public class RDBDocumentStorePerformance
             stmt.setString(idx, id);
         }
     }
+
+    private static Connection close(Connection c) {
+        if (c != null) {
+            try {
+                c.close();
+            } catch (SQLException ex) {
+                // ignored
+            }
+        }
+        return null;
+    }
+
+    private static PreparedStatement close(PreparedStatement s) {
+        if (s != null) {
+            try {
+                s.close();
+            } catch (SQLException ex) {
+                // ignored
+            }
+        }
+        return null;
+    }
 }