diff --git a/server/src/main/java/org/cloudfoundry/identity/uaa/oauth/UaaTokenStore.java b/server/src/main/java/org/cloudfoundry/identity/uaa/oauth/UaaTokenStore.java index e4dedc42127..36c579e308e 100644 --- a/server/src/main/java/org/cloudfoundry/identity/uaa/oauth/UaaTokenStore.java +++ b/server/src/main/java/org/cloudfoundry/identity/uaa/oauth/UaaTokenStore.java @@ -25,6 +25,7 @@ import org.cloudfoundry.identity.uaa.util.UaaStringUtils; import org.cloudfoundry.identity.uaa.zone.IdentityZoneHolder; import org.springframework.dao.DataIntegrityViolationException; +import org.springframework.dao.DeadlockLoserDataAccessException; import org.springframework.dao.EmptyResultDataAccessException; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.RowMapper; @@ -216,11 +217,15 @@ protected void performExpirationClean() { if ((System.currentTimeMillis()-last) > getExpirationTime()) { //avoid concurrent deletes from the same UAA - performance improvement if (lastClean.compareAndSet(last, last+getExpirationTime())) { - JdbcTemplate template = new JdbcTemplate(dataSource); - int expired = template.update(SQL_EXPIRE_STATEMENT, System.currentTimeMillis()); - logger.debug("[oauth_code] Removed "+expired+" expired entries."); - expired = template.update(SQL_CLEAN_STATEMENT, new Timestamp(System.currentTimeMillis()-LEGACY_CODE_EXPIRATION_TIME)); - logger.debug("[oauth_code] Removed "+expired+" old entries."); + try { + JdbcTemplate template = new JdbcTemplate(dataSource); + int expired = template.update(SQL_EXPIRE_STATEMENT, System.currentTimeMillis()); + logger.debug("[oauth_code] Removed "+expired+" expired entries."); + expired = template.update(SQL_CLEAN_STATEMENT, new Timestamp(System.currentTimeMillis()-LEGACY_CODE_EXPIRATION_TIME)); + logger.debug("[oauth_code] Removed "+expired+" old entries."); + } catch (DeadlockLoserDataAccessException e) { + logger.debug("[oauth code] Deadlock trying to expire entries, ignored."); + } } } diff --git a/server/src/test/java/org/cloudfoundry/identity/uaa/oauth/UaaTokenStoreTests.java b/server/src/test/java/org/cloudfoundry/identity/uaa/oauth/UaaTokenStoreTests.java index c2df72b095a..2674a73c7d9 100644 --- a/server/src/test/java/org/cloudfoundry/identity/uaa/oauth/UaaTokenStoreTests.java +++ b/server/src/test/java/org/cloudfoundry/identity/uaa/oauth/UaaTokenStoreTests.java @@ -24,6 +24,7 @@ import org.cloudfoundry.identity.uaa.zone.IdentityZone; import org.junit.Before; import org.junit.Test; +import org.springframework.dao.DeadlockLoserDataAccessException; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; @@ -44,6 +45,7 @@ import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.sql.Connection; +import java.sql.PreparedStatement; import java.sql.SQLException; import java.sql.SQLFeatureNotSupportedException; import java.sql.Timestamp; @@ -314,6 +316,27 @@ public void testCleanUpUnusedOldTokens_MySQL_In_Another_Timezone() throws Except } } + @Test + public void testCleanUpExpiredTokensDeadlockLoser() throws Exception { + Connection con = dataSource.getConnection(); + try { + Connection expirationLoser = (Connection) Proxy.newProxyInstance(getClass().getClassLoader(), + new Class[]{Connection.class}, + new ExpirationLoserConnection(con)); + + SameConnectionDataSource sameConnectionDataSource = new SameConnectionDataSource(expirationLoser); + + store = new UaaTokenStore(sameConnectionDataSource, 1); + int count = 10; + for (int i=0; i 0) { + String sql = (String) args[0]; + if (sql.startsWith("delete from oauth_code where expiresat ")) { + PreparedStatement stmt = (PreparedStatement) method.invoke(con, args); + return Proxy.newProxyInstance(getClass().getClassLoader(), + new Class[]{PreparedStatement.class}, + new ExpirationLoserPreparedStatement(stmt)); + } + } + } + return method.invoke(con, args); + } + } + private static final byte[] UAA_AUTHENTICATION_DATA_OLD_STYLE = new byte[] {123, 34, 111, 97, 117, 116, 104, 50, 82, 101, 113, 117, 101, 115, 116, 46, 114, 101, 115, 112, 111, 110, 115, 101, 84, 121, 112, 101, 115, 34, 58, 91, 93, 44, 34, 111, 97, 117, 116, 104, 50, 82, 101, 113, 117, 101, 115, 116, 46, 114, 101, 115, 111, 117, 114, 99, 101, 73, 100, 115, 34, 58, 91, 93, 44, 34, 117, 115, 101, 114, 65, 117, 116, 104, 101, 110, 116, 105, 99, 97, 116, 105, 111, 110, 46, 117, 97, 97, 80, 114, 105, 110, 99, 105, 112, 97, 108, 34, 58, 34, 123, 92, 34, 105, 100, 92, 34, 58, 92, 34, 117, 115, 101, 114, 105, 100, 92, 34, 44, 92, 34, 110, 97, 109, 101, 92, 34, 58, 92, 34, 117, 115, 101, 114, 110, 97, 109, 101, 92, 34, 44, 92, 34, 101, 109, 97, 105, 108, 92, 34, 58, 92, 34, 117, 115, 101, 114, 110, 97, 109, 101, 64, 116, 101, 115, 116, 46, 111, 114, 103, 92, 34, 44, 92, 34, 111, 114, 105, 103, 105, 110, 92, 34, 58, 92, 34, 117, 97, 97, 92, 34, 44, 92, 34, 101, 120, 116, 101, 114, 110, 97, 108, 73, 100, 92, 34, 58, 110, 117, 108, 108, 44, 92, 34, 122, 111, 110, 101, 73, 100, 92, 34, 58, 92, 34, 117, 97, 97, 92, 34, 125, 34, 44, 34, 111, 97, 117, 116, 104, 50, 82, 101, 113, 117, 101, 115, 116, 46, 114, 101, 113, 117, 101, 115, 116, 80, 97, 114, 97, 109, 101, 116, 101, 114, 115, 34, 58, 123, 34, 103, 114, 97, 110, 116, 95, 116, 121, 112, 101, 34, 58, 34, 112, 97, 115, 115, 119, 111, 114, 100, 34, 44, 34, 99, 108, 105, 101, 110, 116, 95, 105, 100, 34, 58, 34, 99, 108, 105, 101, 110, 116, 105, 100, 34, 44, 34, 115, 99, 111, 112, 101, 34, 58, 34, 111, 112, 101, 110, 105, 100, 34, 125, 44, 34, 111, 97, 117, 116, 104, 50, 82, 101, 113, 117, 101, 115, 116, 46, 114, 101, 100, 105, 114, 101, 99, 116, 85, 114, 105, 34, 58, 110, 117, 108, 108, 44, 34, 117, 115, 101, 114, 65, 117, 116, 104, 101, 110, 116, 105, 99, 97, 116, 105, 111, 110, 46, 97, 117, 116, 104, 111, 114, 105, 116, 105, 101, 115, 34, 58, 91, 34, 111, 112, 101, 110, 105, 100, 34, 93, 44, 34, 111, 97, 117, 116, 104, 50, 82, 101, 113, 117, 101, 115, 116, 46, 97, 117, 116, 104, 111, 114, 105, 116, 105, 101, 115, 34, 58, 91, 34, 111, 97, 117, 116, 104, 46, 108, 111, 103, 105, 110, 34, 93, 44, 34, 111, 97, 117, 116, 104, 50, 82, 101, 113, 117, 101, 115, 116, 46, 99, 108, 105, 101, 110, 116, 73, 100, 34, 58, 34, 99, 108, 105, 101, 110, 116, 105, 100, 34, 44, 34, 111, 97, 117, 116, 104, 50, 82, 101, 113, 117, 101, 115, 116, 46, 97, 112, 112, 114, 111, 118, 101, 100, 34, 58, 116, 114, 117, 101, 44, 34, 111, 97, 117, 116, 104, 50, 82, 101, 113, 117, 101, 115, 116, 46, 115, 99, 111, 112, 101, 34, 58, 91, 34, 111, 112, 101, 110, 105, 100, 34, 93, 125}; }