詳解Spring不同數據庫異常如何抽象的_第1頁
詳解Spring不同數據庫異常如何抽象的_第2頁
詳解Spring不同數據庫異常如何抽象的_第3頁
詳解Spring不同數據庫異常如何抽象的_第4頁
詳解Spring不同數據庫異常如何抽象的_第5頁
已閱讀5頁,還剩3頁未讀, 繼續免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

第詳解Spring不同數據庫異常如何抽象的//SQLErrorCodesFactory構造方法中,生成的errorCodesMap,map的內容來自org/springframework/jdbc/support/sql-error-codes.xml文件

protectedSQLErrorCodesFactory(){

MaperrorCodes;

try{

DefaultListableBeanFactorylbf=newDefaultListableBeanFactory();

lbf.setBeanClassLoader(this.getClass().getClassLoader());

XmlBeanDefinitionReaderbdr=newXmlBeanDefinitionReader(lbf);

Resourceresource=this.loadResource("org/springframework/jdbc/support/sql-error-codes.xml");

if(resource!=nullresource.exists()){

bdr.loadBeanDefinitions(resource);

}else{

("Defaultsql-error-codes.xmlnotfound(shouldbeincludedinspring-jdbcjar)");

resource=this.loadResource("sql-error-codes.xml");

if(resource!=nullresource.exists()){

bdr.loadBeanDefinitions(resource);

logger.debug("Foundcustomsql-error-codes.xmlfileattherootoftheclasspath");

errorCodes=lbf.getBeansOfType(SQLErrorCodes.class,true,false);

if(logger.isTraceEnabled()){

logger.trace("SQLErrorCodesloaded:"+errorCodes.keySet());

}catch(BeansExceptionvar5){

logger.warn("ErrorloadingSQLerrorcodesfromconfigfile",var5);

errorCodes=Collections.emptyMap();

this.errorCodesMap=errorCodes;

}

sql-error-codes.xml文件中配置了各個數據庫的主要的錯誤碼

這里列舉了MYSQL部分,當然還有其他部分,我們可以看到唯一性約束錯誤碼是1062,就可以翻譯成DuplicateKeyException異常了

beanid="MySQL"

propertyname="databaseProductNames"

list

valueMySQL/value

valueMariaDB/value

/list

/property

propertyname="badSqlGrammarCodes"

value1054,1064,1146/value

/property

propertyname="duplicateKeyCodes"

value1062/value

/property

propertyname="dataIntegrityViolationCodes"

value630,839,840,893,1169,1215,1216,1217,1364,1451,1452,1557/value

/property

propertyname="dataAccessResourceFailureCodes"

value1/value

/property

propertyname="cannotAcquireLockCodes"

value1205,3572/value

/property

propertyname="deadlockLoserCodes"

value1213/value

/property

/bean

你已經看到,比如上面的錯誤碼值列舉了一部分,如果出現了一個不在其中的錯誤碼肯定是匹配不到,Spring當然能想到這種情況了

*@公-眾-號:程序員阿牛

*在AbstractFallbackSQLExceptionTranslator中,看到如果查找失敗會獲取下一個后續轉換器

@Nullable

publicDataAccessExceptiontranslate(Stringtask,@NullableStringsql,SQLExceptionex){

Assert.notNull(ex,"CannottranslateanullSQLException");

DataAccessExceptiondae=this.doTranslate(task,sql,ex);

if(dae!=null){

returndae;

}else{

SQLExceptionTranslatorfallback=this.getFallbackTranslator();

returnfallback!=nullfallback.translate(task,sql,ex):null;

}

SQLErrorCodeSQLExceptionTranslator的后置轉換器是什么?

//構造方法中已經指定,SQLExceptionSubclassTranslator

publicSQLErrorCodeSQLExceptionTranslator(){

this.setFallbackTranslator(newSQLExceptionSubclassTranslator());

}

SQLExceptionSubclassTranslator的轉換方法邏輯如下:

*@公-眾-號:程序員阿牛

*可以看出實際按照子類類型來判斷,返回相應的錯誤類,如果匹配不到,則找到下一個處理器,這里的處理其我們可以根據構造方法青松找到*SQLStateSQLExceptionTranslator

@Nullable

protectedDataAccessExceptiondoTranslate(Stringtask,@NullableStringsql,SQLExceptionex){

if(exinstanceofSQLTransientException){

if(exinstanceofSQLTransientConnectionException){

returnnewTransientDataAccessResourceException(this.buildMessage(task,sql,ex),ex);

if(exinstanceofSQLTransactionRollbackException){

returnnewConcurrencyFailureException(this.buildMessage(task,sql,ex),ex);

if(exinstanceofSQLTimeoutException){

returnnewQueryTimeoutException(this.buildMessage(task,sql,ex),ex);

}elseif(exinstanceofSQLNonTransientException){

if(exinstanceofSQLNonTransientConnectionException){

returnnewDataAccessResourceFailureException(this.buildMessage(task,sql,ex),ex);

if(exinstanceofSQLDataException){

returnnewDataIntegrityViolationException(this.buildMessage(task,sql,ex),ex);

if(exinstanceofSQLIntegrityConstraintViolationException){

returnnewDataIntegrityViolationException(this.buildMessage(task,sql,ex),ex);

if(exinstanceofSQLInvalidAuthorizationSpecException){

returnnewPermissionDeniedDataAccessException(this.buildMessage(task,sql,ex),ex);

if(exinstanceofSQLSyntaxErrorException){

returnnewBadSqlGrammarException(task,sql!=nullsql:"",ex);

if(exinstanceofSQLFeatureNotSupportedException){

returnnewInvalidDataAccessApiUsageException(this.buildMessage(task,sql,ex),ex);

}elseif(exinstanceofSQLRecoverableException){

returnnewRecoverableDataAccessException(this.buildMessage(task,sql,ex),ex);

returnnull;

}

SQLStateSQLExceptionTranslator的轉換方法:

*@公-眾-號:程序員阿牛

*可以看出根據SQLState的前兩位來判斷異常,根據匹配結果返回相應的異常信息

@Nullable

protectedDataAccessExceptiondoTranslate(Stringtask,@NullableStringsql,SQLExceptionex){

StringsqlState=this.getSqlState(ex);

if(sqlState!=nullsqlState.length()=2){

StringclassCode=sqlState.substring(0,2);

if(this.logger.isDebugEnabled()){

this.logger.debug("ExtractedSQLstateclass'"+classCode+"'fromvalue'"+sqlState+"'");

if(BAD_SQL_GRAMMAR_CODES.contains(classCode)){

returnnewBadSqlGrammarException(task,sql!=nullsql:"",ex);

if(DATA_INTEGRITY_VIOLATION_CODES.contains(classCode)){

returnnewDataIntegrityViolationException(this.buildMessage(task,sql,ex),ex);

if(DATA_ACCESS_RESOURCE_FAILURE_CODES.contains(classCode)){

returnnewDataAccessResourceFailureException(this.buildMessage(task,sql,ex),ex);

if(TRANSIENT_DATA_ACCESS_RESOURCE_CODES.contains(classCode)){

returnnewTransientDataAccessResourceException(this.buildMessage(task,sql,ex),ex);

if(CONCURRENCY_FAILURE_CODES.contains(classCode)){

returnnewConcurrencyFailureException(this.buildMessage(task,sql,ex),ex);

returnex.getClass().getName().contains("Timeout")newQueryTimeoutException(this.buildMessage(task,sq

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論