Mysql lock wait timeout
阿新 • • 發佈:2020-08-06
前段時間遇到一個問題,有個事務內的程式碼,但是顯然沒有全部回滾,導致業務事務不完整;error message如下
org.springframework.dao.CannotAcquireLockException:
### Error updating database. Cause: com.mysql.cj.jdbc.exceptions.MySQLTransactionRollbackException: Lock wait timeout exceeded; try restarting transaction
如上顯示,遇到的MySQLTransactionRollbackException,觸發原因是“鎖等待超時”,從mysql connector中丟擲,丟擲位置的程式碼如下,可以看到
#SQLError.class public static SQLException createSQLException(String message, String sqlState, int vendorErrorCode, boolean isTransient, Throwable cause, ExceptionInterceptor interceptor) { try { SQLException sqlEx = null; if (sqlState != null) { if (sqlState.startsWith("08")) { if (isTransient) { sqlEx = new SQLTransientConnectionException(message, sqlState, vendorErrorCode); } else { sqlEx = new SQLNonTransientConnectionException(message, sqlState, vendorErrorCode); } } else if (sqlState.startsWith("22")) { sqlEx = new SQLDataException(message, sqlState, vendorErrorCode); } else if (sqlState.startsWith("23")) { sqlEx = new SQLIntegrityConstraintViolationException(message, sqlState, vendorErrorCode); } else if (sqlState.startsWith("42")) { sqlEx = new SQLSyntaxErrorException(message, sqlState, vendorErrorCode); //40開頭的sqlstate都會丟擲這個異常 } else if (sqlState.startsWith("40")) { sqlEx = new MySQLTransactionRollbackException(message, sqlState, vendorErrorCode); } else if (sqlState.startsWith("70100")) { sqlEx = new MySQLQueryInterruptedException(message, sqlState, vendorErrorCode); } else { sqlEx = new SQLException(message, sqlState, vendorErrorCode); } } else { sqlEx = new SQLException(message, sqlState, vendorErrorCode); } if (cause != null) { try { sqlEx.initCause(cause); } catch (Throwable t) { // we're not going to muck with that here, since it's an error condition anyway! } } return runThroughExceptionInterceptor(interceptor, sqlEx); } catch (Exception sqlEx) { SQLException unexpectedEx = new SQLException( "Unable to create correct SQLException class instance, error class/codes may be incorrect. Reason: " + Util.stackTraceToString(sqlEx), MysqlErrorNumbers.SQL_STATE_GENERAL_ERROR); return runThroughExceptionInterceptor(interceptor, unexpectedEx); } }
在mysql connector文件中有如下表格
到這裡有幾個疑問,1.什麼情況下會造成lock wait timeout?2.為什麼lock timeout為什麼事務不全部回滾?3.為什麼這裡的異常命名用MySQLTransactionRollbackException?
1.什麼情況下會造成lock wait timeout?
在mysql官網可以看得到關於lock wait timeout相關的配置如下,由於一行資料被另一個事務鎖定,導致當下的事務一直等待,直至超時!
2.為什麼lock timeout為什麼事務不全部回滾?
繼續往下看,可以知道mysql服務隊鎖等待超時的情況,並不會整個回滾該資料