Spring Dao异常体系

Spring 抽象了一套和底层持久化技术无关的 、 面向 DAO 层的异常体系。在内部:通过异常转换器(SQLExceptionTranslator)将不同持久化技术的异常(SQLExceptionSQLException 与具体数据库强相关)转换成 Spring 的持久层异常(DataAccessException),实现统一管理。

DataAccessException

DataAccessException TransientDataAccessException NonTransientDataAccessException ScriptException RecoverableDataAccessException

Spring-Dao层 Root根异常,由标准的 SQLException转化而来。

那么SQLException如何转化为DataAccessException的呢?

答:在 org.springframework.jdbc.support 包中定义了 SQLExceptionTranslator 接口。

	DataAccessException translate(String task, @Nullable String sql, SQLException ex);

入参是标准的SQLException,返回的是转换后的DataAccessException

该接口的两个实现类 SQLErrorCodeSQLExceptionTranslatorSQLStateSQLExceptionTranslator

SQLExceptionTranslator SQLErrorCodeSQLExceptionTranslator SQLStateSQLExceptionTranslator

SQLErrorCodeSQLExceptionTranslator是根据SQLException的错误码SQLState进行转化,其中SQL错误码和具体异常映射关系是在:sql-error-codes.xml中声明的。如下格式

<bean id="MySQL" class="org.springframework.jdbc.support.SQLErrorCodes">
   <property name="databaseProductNames">
      <list>
         <value>MySQL</value>
         <value>MariaDB</value>
      </list>
   </property>
   <property name="badSqlGrammarCodes">
      <value>1054,1064,1146</value>
   </property>
   <property name="duplicateKeyCodes">
      <value>1062</value>
   </property>
   <property name="dataIntegrityViolationCodes">
      <value>630,839,840,893,1169,1215,1216,1217,1364,1451,1452,1557</value>
   </property>
   <property name="dataAccessResourceFailureCodes">
      <value>1</value>
   </property>
   <property name="cannotAcquireLockCodes">
      <value>1205,3572</value>
   </property>
   <property name="deadlockLoserCodes">
      <value>1213</value>
   </property>
</bean>

<bean id="Oracle" class="org.springframework.jdbc.support.SQLErrorCodes">
   <property name="badSqlGrammarCodes">
      <value>900,903,904,917,936,942,17006,6550</value>
   </property>
   <property name="invalidResultSetAccessCodes">
      <value>17003</value>
   </property>
   <property name="duplicateKeyCodes">
      <value>1</value>
   </property>
   <property name="dataIntegrityViolationCodes">
      <value>1400,1722,2291,2292</value>
   </property>
   <property name="dataAccessResourceFailureCodes">
      <value>17002,17447</value>
   </property>
   <property name="cannotAcquireLockCodes">
      <value>54,30006</value>
   </property>
   <property name="cannotSerializeTransactionCodes">
      <value>8177</value>
   </property>
   <property name="deadlockLoserCodes">
      <value>60</value>
   </property>
</bean>

SQLStateSQLExceptionTranslator是根据SQLException中的状态码(SQLState的前两位)进行转化的。

TransientDataAccessException

TransientDataAccessException QueryTimeoutException ConcurrencyFailureException PessimisticLockingFailureException CannotAcquireLockException CannotSerializeTransactionException DeadlockLoserDataAccessException OptimisticLockingFailureException TransientDataAccessResourceException

TransientDataAccessException,瞬态异常,失败的操作重试可能会成功。

比如:QueryTimeoutException、CannotAcquireLockException异常都属于瞬态异常。

异常描述
QueryTimeoutException查询超时(Exception to be thrown on a query timeout. )
ConcurrencyFailureException并发相关的异常(Exception thrown on concurrency failure.)
PessimisticLockingFailureException悲观锁,锁定引发的异常(Exception thrown on a pessimistic locking violation.)
OptimisticLockingFailureException乐观锁,锁定引发的异常(Exception thrown on an optimistic locking violation.)
CannotAcquireLockException获取锁失败(Exception thrown on failure to acquire a lock during an update,for example during a “select for update” statement.)
CannotSerializeTransactionException在串行(serialized)的事务隔离级别中,由于update竞争失败抛出来的异常(Exception thrown on failure to complete a transaction in serializedmode due to update conflicts)
DeadlockLoserDataAccessException死锁
TransientDataAccessResourceException资源暂时出现故障时导致的数据访问异常,可以进行重试(Data access exception thrown when a resource fails temporarily and the operation can be retried.)

NonTransientDataAccessException

NonTransientDataAccessException DataIntegrityViolationException DuplicateKeyException InvalidDataAccessResourceUsageException BadSqlGrammarException InvalidResultSetAccessException TypeMismatchDataAccessException IncorrectUpdateSemanticsDataAccessException JdbcUpdateAffectedIncorrectNumberOfRowsException NonTransientDataAccessResourceException DataAccessResourceFailureException CannotGetJdbcConnectionException DataSourceLookupFailureException UncategorizedDataAccessException SQLWarningException UncategorizedSQLException DataRetrievalFailureException CleanupFailureDataAccessException PermissionDeniedDataAccessException IncorrectResultSizeDataAccessException EmptyResultDataAccessException LobRetrievalFailureException IncorrectResultSetColumnCountException InvalidDataAccessApiUsageException SqlXmlFeatureNotImplementedException

NonTransientDataAccessException,非瞬态异常,重试仍然会失败。比如:BadSqlGrammarException就是该异常的子类。

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值