diff --git a/spring-integration-core/src/main/java/org/springframework/integration/support/leader/LockRegistryLeaderInitiator.java b/spring-integration-core/src/main/java/org/springframework/integration/support/leader/LockRegistryLeaderInitiator.java index 7b5dfa129c..bceb6ac7e4 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/support/leader/LockRegistryLeaderInitiator.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/support/leader/LockRegistryLeaderInitiator.java @@ -347,9 +347,16 @@ public class LockRegistryLeaderInitiator implements SmartLifecycle, DisposableBe } catch (Exception e) { if (this.locked) { - LockRegistryLeaderInitiator.this.locks.obtain(this.lockKey) - .unlock(); this.locked = false; + try { + LockRegistryLeaderInitiator.this.locks.obtain(this.lockKey) + .unlock(); + } + catch (Exception e1) { + logger.debug("Could not unlock - treat as broken. " + + "Revoking " + (isRunning() ? " and retrying..." : "..."), e); + + } // The lock was broken and we are no longer leader handleRevoked(); if (isRunning()) { @@ -375,12 +382,17 @@ public class LockRegistryLeaderInitiator implements SmartLifecycle, DisposableBe } finally { if (this.locked) { - LockRegistryLeaderInitiator.this.locks.obtain(this.lockKey) - .unlock(); + this.locked = false; + try { + LockRegistryLeaderInitiator.this.locks.obtain(this.lockKey) + .unlock(); + } + catch (Exception e) { + logger.debug("Could not unlock during stop - treat as broken. Revoking...", e); + } // We are stopping, therefore not leading any more handleRevoked(); } - this.locked = false; } return null; } diff --git a/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/leader/JdbcLockRegistryLeaderInitiatorTests.java b/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/leader/JdbcLockRegistryLeaderInitiatorTests.java index 1e4a7e60c0..ad3d0a15b5 100644 --- a/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/leader/JdbcLockRegistryLeaderInitiatorTests.java +++ b/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/leader/JdbcLockRegistryLeaderInitiatorTests.java @@ -163,6 +163,35 @@ public class JdbcLockRegistryLeaderInitiatorTests { initiator1.stop(); } + @Test + public void testLostConnection() throws InterruptedException { + CountDownLatch granted = new CountDownLatch(1); + CountingPublisher countingPublisher = new CountingPublisher(granted); + + DefaultLockRepository lockRepository = new DefaultLockRepository(dataSource); + lockRepository.afterPropertiesSet(); + LockRegistryLeaderInitiator initiator = new LockRegistryLeaderInitiator(new JdbcLockRegistry(lockRepository)); + initiator.setLeaderEventPublisher(countingPublisher); + + initiator.start(); + + assertThat(granted.await(10, TimeUnit.SECONDS), is(true)); + + destroy(); + + assertThat(countingPublisher.revoked.await(10, TimeUnit.SECONDS), is(true)); + + granted = new CountDownLatch(1); + countingPublisher = new CountingPublisher(granted); + initiator.setLeaderEventPublisher(countingPublisher); + + init(); + + assertThat(granted.await(10, TimeUnit.SECONDS), is(true)); + + initiator.stop(); + } + private static class CountingPublisher implements LeaderEventPublisher { private CountDownLatch granted;