Ignore failed rename operation for deleted session
In scenario with concurrent requests attempting to change session id, the "ERR no such key" error will occur for a thread that comes in second. This commit addresses the problem by ignoring the aforementioned error. Resolves: #1270
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2014-2018 the original author or authors.
|
* Copyright 2014-2019 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -600,6 +600,25 @@ public class RedisOperationsSessionRepositoryITests extends AbstractRedisITests
|
|||||||
assertThat(this.repository.findById(sessionId)).isNull();
|
assertThat(this.repository.findById(sessionId)).isNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test // gh-1270
|
||||||
|
public void changeSessionIdSaveConcurrently() {
|
||||||
|
RedisSession toSave = this.repository.createSession();
|
||||||
|
String originalId = toSave.getId();
|
||||||
|
this.repository.save(toSave);
|
||||||
|
|
||||||
|
RedisSession copy1 = this.repository.findById(originalId);
|
||||||
|
RedisSession copy2 = this.repository.findById(originalId);
|
||||||
|
|
||||||
|
copy1.changeSessionId();
|
||||||
|
this.repository.save(copy1);
|
||||||
|
copy2.changeSessionId();
|
||||||
|
this.repository.save(copy2);
|
||||||
|
|
||||||
|
assertThat(this.repository.findById(originalId)).isNull();
|
||||||
|
assertThat(this.repository.findById(copy1.getId())).isNotNull();
|
||||||
|
assertThat(this.repository.findById(copy2.getId())).isNull();
|
||||||
|
}
|
||||||
|
|
||||||
private String getSecurityName() {
|
private String getSecurityName() {
|
||||||
return this.context.getAuthentication().getName();
|
return this.context.getAuthentication().getName();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2014-2018 the original author or authors.
|
* Copyright 2014-2019 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -864,24 +864,34 @@ public class RedisOperationsSessionRepository implements
|
|||||||
if (!isNew()) {
|
if (!isNew()) {
|
||||||
String originalSessionIdKey = getSessionKey(this.originalSessionId);
|
String originalSessionIdKey = getSessionKey(this.originalSessionId);
|
||||||
String sessionIdKey = getSessionKey(sessionId);
|
String sessionIdKey = getSessionKey(sessionId);
|
||||||
RedisOperationsSessionRepository.this.sessionRedisOperations.rename(
|
try {
|
||||||
originalSessionIdKey, sessionIdKey);
|
RedisOperationsSessionRepository.this.sessionRedisOperations
|
||||||
|
.rename(originalSessionIdKey, sessionIdKey);
|
||||||
|
}
|
||||||
|
catch (NonTransientDataAccessException ex) {
|
||||||
|
handleErrNoSuchKeyError(ex);
|
||||||
|
}
|
||||||
String originalExpiredKey = getExpiredKey(this.originalSessionId);
|
String originalExpiredKey = getExpiredKey(this.originalSessionId);
|
||||||
String expiredKey = getExpiredKey(sessionId);
|
String expiredKey = getExpiredKey(sessionId);
|
||||||
try {
|
try {
|
||||||
RedisOperationsSessionRepository.this.sessionRedisOperations.rename(
|
RedisOperationsSessionRepository.this.sessionRedisOperations
|
||||||
originalExpiredKey, expiredKey);
|
.rename(originalExpiredKey, expiredKey);
|
||||||
}
|
}
|
||||||
catch (NonTransientDataAccessException ex) {
|
catch (NonTransientDataAccessException ex) {
|
||||||
if (!"ERR no such key".equals(NestedExceptionUtils
|
handleErrNoSuchKeyError(ex);
|
||||||
.getMostSpecificCause(ex).getMessage())) {
|
|
||||||
throw ex;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.originalSessionId = sessionId;
|
this.originalSessionId = sessionId;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void handleErrNoSuchKeyError(NonTransientDataAccessException ex) {
|
||||||
|
if (!"ERR no such key"
|
||||||
|
.equals(NestedExceptionUtils.getMostSpecificCause(ex).getMessage())) {
|
||||||
|
throw ex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user