Detect SQL state 57014 as QueryTimeoutException
Closes gh-35073
This commit is contained in:
parent
45d887f973
commit
e33adadc62
|
@ -70,6 +70,11 @@ public class SQLStateSQLExceptionTranslator extends AbstractFallbackSQLException
|
|||
"44" // With check violation
|
||||
);
|
||||
|
||||
private static final Set<String> PESSIMISTIC_LOCKING_FAILURE_CODES = Set.of(
|
||||
"40", // Transaction rollback
|
||||
"61" // Oracle: deadlock
|
||||
);
|
||||
|
||||
private static final Set<String> DATA_ACCESS_RESOURCE_FAILURE_CODES = Set.of(
|
||||
"08", // Connection exception
|
||||
"53", // PostgreSQL: insufficient resources (for example, disk full)
|
||||
|
@ -84,11 +89,6 @@ public class SQLStateSQLExceptionTranslator extends AbstractFallbackSQLException
|
|||
"S1" // DB2: communication failure
|
||||
);
|
||||
|
||||
private static final Set<String> PESSIMISTIC_LOCKING_FAILURE_CODES = Set.of(
|
||||
"40", // Transaction rollback
|
||||
"61" // Oracle: deadlock
|
||||
);
|
||||
|
||||
private static final Set<Integer> DUPLICATE_KEY_ERROR_CODES = Set.of(
|
||||
1, // Oracle
|
||||
301, // SAP HANA
|
||||
|
@ -117,18 +117,21 @@ public class SQLStateSQLExceptionTranslator extends AbstractFallbackSQLException
|
|||
}
|
||||
return new DataIntegrityViolationException(buildMessage(task, sql, ex), ex);
|
||||
}
|
||||
else if (DATA_ACCESS_RESOURCE_FAILURE_CODES.contains(classCode)) {
|
||||
return new DataAccessResourceFailureException(buildMessage(task, sql, ex), ex);
|
||||
}
|
||||
else if (TRANSIENT_DATA_ACCESS_RESOURCE_CODES.contains(classCode)) {
|
||||
return new TransientDataAccessResourceException(buildMessage(task, sql, ex), ex);
|
||||
}
|
||||
else if (PESSIMISTIC_LOCKING_FAILURE_CODES.contains(classCode)) {
|
||||
if (indicatesCannotAcquireLock(sqlState)) {
|
||||
return new CannotAcquireLockException(buildMessage(task, sql, ex), ex);
|
||||
}
|
||||
return new PessimisticLockingFailureException(buildMessage(task, sql, ex), ex);
|
||||
}
|
||||
else if (DATA_ACCESS_RESOURCE_FAILURE_CODES.contains(classCode)) {
|
||||
if (indicatesQueryTimeout(sqlState)) {
|
||||
return new QueryTimeoutException(buildMessage(task, sql, ex), ex);
|
||||
}
|
||||
return new DataAccessResourceFailureException(buildMessage(task, sql, ex), ex);
|
||||
}
|
||||
else if (TRANSIENT_DATA_ACCESS_RESOURCE_CODES.contains(classCode)) {
|
||||
return new TransientDataAccessResourceException(buildMessage(task, sql, ex), ex);
|
||||
}
|
||||
}
|
||||
|
||||
// For MySQL: exception class name indicating a timeout?
|
||||
|
@ -184,4 +187,13 @@ public class SQLStateSQLExceptionTranslator extends AbstractFallbackSQLException
|
|||
return "40001".equals(sqlState);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the given SQL state indicates a {@link QueryTimeoutException},
|
||||
* with SQL state 57014 as a specific indication.
|
||||
* @param sqlState the SQL state value
|
||||
*/
|
||||
static boolean indicatesQueryTimeout(@Nullable String sqlState) {
|
||||
return "57014".equals(sqlState);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ import org.springframework.dao.DataAccessResourceFailureException;
|
|||
import org.springframework.dao.DataIntegrityViolationException;
|
||||
import org.springframework.dao.DuplicateKeyException;
|
||||
import org.springframework.dao.PessimisticLockingFailureException;
|
||||
import org.springframework.dao.QueryTimeoutException;
|
||||
import org.springframework.dao.TransientDataAccessResourceException;
|
||||
import org.springframework.jdbc.BadSqlGrammarException;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
@ -109,6 +110,11 @@ class SQLStateSQLExceptionTranslatorTests {
|
|||
assertTranslation("40001", CannotAcquireLockException.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void translateQueryTimeout() {
|
||||
assertTranslation("57014", QueryTimeoutException.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void translateUncategorized() {
|
||||
assertTranslation("00000000", null);
|
||||
|
|
Loading…
Reference in New Issue