]> source.dussan.org Git - sonarqube.git/commitdiff
Improve db migration so that multiple SELECT can be concurrently executed
authorSimon Brandhof <simon.brandhof@sonarsource.com>
Fri, 31 Oct 2014 09:51:37 +0000 (10:51 +0100)
committerSimon Brandhof <simon.brandhof@sonarsource.com>
Fri, 31 Oct 2014 09:51:37 +0000 (10:51 +0100)
server/sonar-server/src/main/java/org/sonar/server/db/migrations/BaseDataChange.java
server/sonar-server/src/main/java/org/sonar/server/db/migrations/DataChange.java

index 32ebbaf443e19e067b7a2131850bb47d13ea988c..58304aa3d1996d680a4f75251b0122b5dbca580a 100644 (file)
  */
 package org.sonar.server.db.migrations;
 
-import org.apache.commons.dbutils.DbUtils;
 import org.sonar.core.persistence.Database;
 
-import java.sql.Connection;
 import java.sql.SQLException;
 
 public abstract class BaseDataChange implements DataChange, DatabaseMigration {
@@ -35,22 +33,11 @@ public abstract class BaseDataChange implements DataChange, DatabaseMigration {
 
   @Override
   public final void execute() throws SQLException {
-    Connection readConnection = null, writeConnection = null;
+    Context context = new Context(db);
     try {
-      readConnection = db.getDataSource().getConnection();
-      readConnection.setAutoCommit(false);
-      if (readConnection.getMetaData().supportsTransactionIsolationLevel(Connection.TRANSACTION_READ_UNCOMMITTED)) {
-        readConnection.setTransactionIsolation(Connection.TRANSACTION_READ_UNCOMMITTED);
-      }
-
-      writeConnection = db.getDataSource().getConnection();
-      writeConnection.setAutoCommit(false);
-      Context context = new Context(db, readConnection, writeConnection);
       execute(context);
-
     } finally {
-      DbUtils.closeQuietly(readConnection);
-      DbUtils.closeQuietly(writeConnection);
+      context.close();
     }
   }
 }
index c901a7825948a05494c75739aa17c23959259ea5..dff05618251f3e0a87d499b06b5327cd7e7c57f4 100644 (file)
  */
 package org.sonar.server.db.migrations;
 
+import com.google.common.collect.Lists;
+import org.apache.commons.dbutils.DbUtils;
 import org.sonar.core.persistence.Database;
 
 import java.sql.Connection;
 import java.sql.SQLException;
+import java.util.List;
 
 public interface DataChange {
 
   class Context {
     private final Database db;
-    private final Connection readConnection, writeConnection;
+    private final List<Connection> connections = Lists.newArrayList();
 
-    public Context(Database db, Connection readConnection, Connection writeConnection) {
+    Context(Database db) {
       this.db = db;
-      this.readConnection = readConnection;
-      this.writeConnection = writeConnection;
     }
 
     public Select prepareSelect(String sql) throws SQLException {
-      return SelectImpl.create(db, readConnection, sql);
+      return SelectImpl.create(db, openReadConnection(), sql);
     }
 
     public Upsert prepareUpsert(String sql) throws SQLException {
-      return UpsertImpl.create(writeConnection, sql);
+      return UpsertImpl.create(openWriteConnection(), sql);
     }
 
     public MassUpdate prepareMassUpdate() throws SQLException {
-      return new MassUpdate(db, readConnection, writeConnection);
+      return new MassUpdate(db, openReadConnection(), openWriteConnection());
+    }
+
+    private Connection openReadConnection() throws SQLException {
+      Connection readConnection = db.getDataSource().getConnection();
+      readConnection.setAutoCommit(false);
+      if (readConnection.getMetaData().supportsTransactionIsolationLevel(Connection.TRANSACTION_READ_UNCOMMITTED)) {
+        readConnection.setTransactionIsolation(Connection.TRANSACTION_READ_UNCOMMITTED);
+      }
+      connections.add(readConnection);
+      return readConnection;
+    }
+
+    private Connection openWriteConnection() throws SQLException {
+      Connection writeConnection = db.getDataSource().getConnection();
+      writeConnection.setAutoCommit(false);
+      connections.add(writeConnection);
+      return writeConnection;
+    }
+
+    void close() {
+      for (Connection connection : connections) {
+        DbUtils.closeQuietly(connection);
+      }
+      connections.clear();
     }
   }