Error、Exception、Checked Exception、Unchecked Exception、Spring事务回滚

Error、Exception是Throwable的两个子类。
RuntimeException是Exception的子类。Exception可分为Checked Exception(受检异常,编译时必须catch或throw)和Unchecked Exception(非受检异常,编译时可以不catch或throw)。RuntimeException及其子类是Unchecked Exception,其他Exception是Checked Exception。

Error是JVM中发生的严重错误。Error是Unchecked。
Error举例:
    ThreadDeath
    VirtualMachineError
        OutOfMemoryError
    AnnotationFormatError
    ServiceConfigurationError
    IOError
    LinkageError
        NoClassDefFoundError
        ClassFormatError    
       AssertionError

Unchecked Exception(JDK1.8中有RuntimeException子类84个)举例:
    RuntimeException
    
    ClassCastException
    IllegalArgumentException
    IllegalStateException
    NullPointerException
    UnsupportedOperationException
    FileSystemAlreadyExistsException
    FileSystemNotFoundException
    DateTimeException
    UncheckedIOException

Checked Exception举例:
    IOException
    SQLException
    ClassNotFoundException

Spring中Error和Unchecked Exception被事务管理器捕获会导致事务回滚。如果事务方法内被catch,没有throw不会回滚,除非手动回滚:TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); 。SQLException不是Unchecked Exception,不会导致事务回滚。Spring中SQLException被置换成DataAccessException,可导致事务回滚。

SQLErrorCodeSQLExceptionTranslator:

    @Nullable
    protected DataAccessException doTranslate(String task, @Nullable String sql, SQLException ex) {
        SQLException sqlEx = ex;
        if (ex instanceof BatchUpdateException && ex.getNextException() != null) {
            SQLException nestedSqlEx = ex.getNextException();
            if (nestedSqlEx.getErrorCode() > 0 || nestedSqlEx.getSQLState() != null) {
                this.logger.debug("Using nested SQLException from the BatchUpdateException");
                sqlEx = nestedSqlEx;
            }
        }

        DataAccessException dex = this.customTranslate(task, sql, sqlEx);
        if (dex != null) {
            return dex;
        } else {
            if (this.sqlErrorCodes != null) {
                SQLExceptionTranslator customTranslator = this.sqlErrorCodes.getCustomSqlExceptionTranslator();
                if (customTranslator != null) {
                    DataAccessException customDex = customTranslator.translate(task, sql, sqlEx);
                    if (customDex != null) {
                        return customDex;
                    }
                }
            }

            String errorCode;
            if (this.sqlErrorCodes != null) {
                if (this.sqlErrorCodes.isUseSqlStateForTranslation()) {
                    errorCode = sqlEx.getSQLState();
                } else {
                    SQLException current;
                    for(current = sqlEx; current.getErrorCode() == 0 && current.getCause() instanceof SQLException; current = (SQLException)current.getCause()) {
                    }

                    errorCode = Integer.toString(current.getErrorCode());
                }

                if (errorCode != null) {
                    CustomSQLErrorCodesTranslation[] customTranslations = this.sqlErrorCodes.getCustomTranslations();
                    if (customTranslations != null) {
                        CustomSQLErrorCodesTranslation[] var8 = customTranslations;
                        int var9 = customTranslations.length;

                        for(int var10 = 0; var10 < var9; ++var10) {
                            CustomSQLErrorCodesTranslation customTranslation = var8[var10];
                            if (Arrays.binarySearch(customTranslation.getErrorCodes(), errorCode) >= 0 && customTranslation.getExceptionClass() != null) {
                                DataAccessException customException = this.createCustomException(task, sql, sqlEx, customTranslation.getExceptionClass());
                                if (customException != null) {
                                    this.logTranslation(task, sql, sqlEx, true);
                                    return customException;
                                }
                            }
                        }
                    }

                    if (Arrays.binarySearch(this.sqlErrorCodes.getBadSqlGrammarCodes(), errorCode) >= 0) {
                        this.logTranslation(task, sql, sqlEx, false);
                        return new BadSqlGrammarException(task, sql != null ? sql : "", sqlEx);
                    }

                    if (Arrays.binarySearch(this.sqlErrorCodes.getInvalidResultSetAccessCodes(), errorCode) >= 0) {
                        this.logTranslation(task, sql, sqlEx, false);
                        return new InvalidResultSetAccessException(task, sql != null ? sql : "", sqlEx);
                    }

                    if (Arrays.binarySearch(this.sqlErrorCodes.getDuplicateKeyCodes(), errorCode) >= 0) {
                        this.logTranslation(task, sql, sqlEx, false);
                        return new DuplicateKeyException(this.buildMessage(task, sql, sqlEx), sqlEx);
                    }

                    if (Arrays.binarySearch(this.sqlErrorCodes.getDataIntegrityViolationCodes(), errorCode) >= 0) {
                        this.logTranslation(task, sql, sqlEx, false);
                        return new DataIntegrityViolationException(this.buildMessage(task, sql, sqlEx), sqlEx);
                    }

                    if (Arrays.binarySearch(this.sqlErrorCodes.getPermissionDeniedCodes(), errorCode) >= 0) {
                        this.logTranslation(task, sql, sqlEx, false);
                        return new PermissionDeniedDataAccessException(this.buildMessage(task, sql, sqlEx), sqlEx);
                    }

                    if (Arrays.binarySearch(this.sqlErrorCodes.getDataAccessResourceFailureCodes(), errorCode) >= 0) {
                        this.logTranslation(task, sql, sqlEx, false);
                        return new DataAccessResourceFailureException(this.buildMessage(task, sql, sqlEx), sqlEx);
                    }

                    if (Arrays.binarySearch(this.sqlErrorCodes.getTransientDataAccessResourceCodes(), errorCode) >= 0) {
                        this.logTranslation(task, sql, sqlEx, false);
                        return new TransientDataAccessResourceException(this.buildMessage(task, sql, sqlEx), sqlEx);
                    }

                    if (Arrays.binarySearch(this.sqlErrorCodes.getCannotAcquireLockCodes(), errorCode) >= 0) {
                        this.logTranslation(task, sql, sqlEx, false);
                        return new CannotAcquireLockException(this.buildMessage(task, sql, sqlEx), sqlEx);
                    }

                    if (Arrays.binarySearch(this.sqlErrorCodes.getDeadlockLoserCodes(), errorCode) >= 0) {
                        this.logTranslation(task, sql, sqlEx, false);
                        return new DeadlockLoserDataAccessException(this.buildMessage(task, sql, sqlEx), sqlEx);
                    }

                    if (Arrays.binarySearch(this.sqlErrorCodes.getCannotSerializeTransactionCodes(), errorCode) >= 0) {
                        this.logTranslation(task, sql, sqlEx, false);
                        return new CannotSerializeTransactionException(this.buildMessage(task, sql, sqlEx), sqlEx);
                    }
                }
            }

            if (this.logger.isDebugEnabled()) {
                if (this.sqlErrorCodes != null && this.sqlErrorCodes.isUseSqlStateForTranslation()) {
                    errorCode = "SQL state '" + sqlEx.getSQLState() + "', error code '" + sqlEx.getErrorCode();
                } else {
                    errorCode = "Error code '" + sqlEx.getErrorCode() + "'";
                }

                this.logger.debug("Unable to translate SQLException with " + errorCode + ", will now try the fallback translator");
            }

            return null;
        }
    }
package org.springframework.dao;

import org.springframework.core.NestedRuntimeException;
import org.springframework.lang.Nullable;

public abstract class DataAccessException extends NestedRuntimeException {
    public DataAccessException(String msg) {
        super(msg);
    }

    public DataAccessException(@Nullable String msg, @Nullable Throwable cause) {
        super(msg, cause);
    }
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

风铃峰顶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值