From 0374e42d350a27b56c0e7f6b82d959ec9fc81e38 Mon Sep 17 00:00:00 2001 From: Simon Brandhof Date: Thu, 3 Nov 2011 16:32:36 +0100 Subject: [PATCH] SONAR-2961 Fail silently when deadlock happens during a purge --- .../sonar/plugins/dbcleaner/api/Purge.java | 4 ++ .../plugins/dbcleaner/runner/PurgeRunner.java | 42 +++++++++++++++---- .../dbcleaner/runner/PurgeRunnerTest.java | 22 ++++++++-- 3 files changed, 57 insertions(+), 11 deletions(-) diff --git a/plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/api/Purge.java b/plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/api/Purge.java index d671085e080..5491df4d06d 100644 --- a/plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/api/Purge.java +++ b/plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/api/Purge.java @@ -46,4 +46,8 @@ public abstract class Purge implements BatchExtension { */ public abstract void purge(PurgeContext context); + @Override + public String toString() { + return getClass().getName(); + } } diff --git a/plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/runner/PurgeRunner.java b/plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/runner/PurgeRunner.java index 12542a55a22..9945d80c650 100644 --- a/plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/runner/PurgeRunner.java +++ b/plugins/sonar-dbcleaner-plugin/src/main/java/org/sonar/plugins/dbcleaner/runner/PurgeRunner.java @@ -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()); diff --git a/plugins/sonar-dbcleaner-plugin/src/test/java/org/sonar/plugins/dbcleaner/runner/PurgeRunnerTest.java b/plugins/sonar-dbcleaner-plugin/src/test/java/org/sonar/plugins/dbcleaner/runner/PurgeRunnerTest.java index c1a84d41e40..ab1ee879b82 100644 --- a/plugins/sonar-dbcleaner-plugin/src/test/java/org/sonar/plugins/dbcleaner/runner/PurgeRunnerTest.java +++ b/plugins/sonar-dbcleaner-plugin/src/test/java/org/sonar/plugins/dbcleaner/runner/PurgeRunnerTest.java @@ -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()); + } } -- 2.39.5