]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-2961 Fail silently when deadlock happens during a purge
authorSimon Brandhof <simon.brandhof@gmail.com>
Thu, 3 Nov 2011 15:32:36 +0000 (16:32 +0100)
committerSimon Brandhof <simon.brandhof@gmail.com>
Thu, 3 Nov 2011 15:32:36 +0000 (16:32 +0100)
plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/api/Purge.java
plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/runner/PurgeRunner.java
plugins/sonar-dbcleaner-plugin/src/test/java/org/sonar/plugins/dbcleaner/runner/PurgeRunnerTest.java

index d671085e080c123ef34709ceee8b41548d8d1998..5491df4d06d31713bc59ceec44cbc26377e1cf03 100644 (file)
@@ -46,4 +46,8 @@ public abstract class Purge implements BatchExtension {
    */
   public abstract void purge(PurgeContext context);
 
+  @Override
+  public String toString() {
+    return getClass().getName();
+  }
 }
index 12542a55a22b434229e4cb16f72de1b12bdeda52..9945d80c650297c3786c7fb458fd030725ad7f8a 100644 (file)
@@ -19,6 +19,7 @@
  */
 package org.sonar.plugins.dbcleaner.runner;
 
+import org.hibernate.HibernateException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.sonar.api.batch.PostJob;
@@ -80,18 +81,43 @@ public final class PurgeRunner implements PostJob {
   private void executeDeprecatedPurges(DefaultPurgeContext context) {
     TimeProfiler profiler = new TimeProfiler();
     for (org.sonar.api.batch.Purge purge : deprecatedPurges) {
-      profiler.start("Purge " + purge.getClass().getName());
-      purge.purge(context);
-      profiler.stop();
+      try {
+        profiler.start("Purge " + purge.getClass().getName());
+        purge.purge(context);
+        session.commit();// force hibernate to commit, so we're sure that the potential raised exception comes from this purge
+        profiler.stop();
+
+      } catch (javax.persistence.PersistenceException e) {
+        // Temporary workaround for MySQL deadlocks. The exception must not fail the build
+        // See https://jira.codehaus.org/browse/SONAR-2961 and https://jira.codehaus.org/browse/SONAR-2190
+        LOG.warn("Fail to execute purge: " + purge, e);
+
+      } catch (HibernateException e) {
+        // Temporary workaround for MySQL deadlocks. The exception must not fail the build
+        // See https://jira.codehaus.org/browse/SONAR-2961 and https://jira.codehaus.org/browse/SONAR-2190
+        LOG.warn("Fail to execute purge: " + purge, e);
+      }
     }
   }
 
   private void executePurges(DefaultPurgeContext context) {
     TimeProfiler profiler = new TimeProfiler();
     for (Purge purge : purges) {
-      profiler.start("Purge " + purge.getClass().getName());
-      purge.purge(context);
-      profiler.stop();
+      try {
+        profiler.start("Purge " + purge.getClass().getName());
+        purge.purge(context);
+        session.commit(); // force hibernate to commit, so we're sure that the potential raised exception comes from this purge
+        profiler.stop();
+      } catch (javax.persistence.PersistenceException e) {
+        // Temporary workaround for MySQL deadlocks. The exception must not fail the build
+        // See https://jira.codehaus.org/browse/SONAR-2961 and https://jira.codehaus.org/browse/SONAR-2190
+        LOG.warn("Fail to execute purge: " + purge, e);
+
+      } catch (HibernateException e) {
+        // Temporary workaround for MySQL deadlocks. The exception must not fail the build
+        // See https://jira.codehaus.org/browse/SONAR-2961 and https://jira.codehaus.org/browse/SONAR-2190
+        LOG.warn("Fail to execute purge: " + purge, e);
+      }
     }
   }
 
@@ -106,8 +132,8 @@ public final class PurgeRunner implements PostJob {
 
   private Snapshot getPreviousLastSnapshot() {
     Query query = session.createQuery(
-        "SELECT s FROM " + Snapshot.class.getSimpleName() + " s " +
-            "WHERE s.status=:status AND s.resourceId=:resourceId AND s.createdAt<:date AND s.id <> :sid ORDER BY s.createdAt DESC");
+      "SELECT s FROM " + Snapshot.class.getSimpleName() + " s " +
+        "WHERE s.status=:status AND s.resourceId=:resourceId AND s.createdAt<:date AND s.id <> :sid ORDER BY s.createdAt DESC");
     query.setParameter("status", Snapshot.STATUS_PROCESSED);
     query.setParameter("resourceId", snapshot.getResourceId());
     query.setParameter("date", snapshot.getCreatedAt());
index c1a84d41e40bb1c800d5045e8828c5ce3b8266a5..ab1ee879b823ee9275a9a075437fb15cc3b9f1b0 100644 (file)
@@ -22,18 +22,19 @@ package org.sonar.plugins.dbcleaner.runner;
 import org.hamcrest.BaseMatcher;
 import org.hamcrest.Description;
 import org.junit.Test;
+import org.mockito.Matchers;
 import org.sonar.api.database.model.Snapshot;
 import org.sonar.api.resources.Project;
 import org.sonar.jpa.test.AbstractDbUnitTestCase;
 import org.sonar.plugins.dbcleaner.api.Purge;
 import org.sonar.plugins.dbcleaner.api.PurgeContext;
 
+import javax.persistence.PersistenceException;
+
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.Matchers.argThat;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.*;
 
 public class PurgeRunnerTest extends AbstractDbUnitTestCase {
 
@@ -118,4 +119,19 @@ public class PurgeRunnerTest extends AbstractDbUnitTestCase {
     when(project.isRoot()).thenReturn(false);
     assertFalse(PurgeRunner.shouldExecuteOn(project));
   }
+
+  /**
+   * See https://jira.codehaus.org/browse/SONAR-2961
+   * Temporarily ignore MySQL deadlocks
+   */
+  @Test
+  public void shouldIgnoreDeadlocks() {
+    Purge purge = mock(Purge.class);
+    doThrow(new PersistenceException()).when(purge).purge((PurgeContext)anyObject());
+
+    PurgeRunner runner = new PurgeRunner(getSession(), new Project(""), new Snapshot(), new Purge[]{purge});
+    runner.purge();// must not raise any exceptions
+
+    verify(purge).purge((PurgeContext)anyObject());
+  }
 }