Java异常体系详解之SQLException

  • 一、SQLException
    • 1、SQLWarning
      • 1.1 DataTruncation
    • 2、RowSetWarning
    • 3、BatchUpdateException
    • 4、SQLClientInfoException
    • 5、SQLNonTransientException
      • 5.1 SQLInvalidAuthorizationSpecException
      • 5.2 SQLDataException
      • 5.3 SQLFeatureNotSupportedException
      • 5.4 SQLIntegrityConstraintViolationException
      • 5.5 SQLSyntaxErrorException
    • 6、SQLRecoverableException
    • 7、SQLTransientException
      • 7.1 SQLTimeoutException
      • 7.2 SQLTransactionRollbackException
    • 8、SerialException
    • 9、SyncFactoryException
    • 10、SyncProviderException
  • ✔️ 一图总结

一、SQLException

SQLException 同RuntimeException、IOException一样,都是 Exception的一个子类。SQLException 及其子类体系提供了有关数据库操作的一系列异常定义描述,这个体系的完整结构信息请查看文末的脑图。

来看关于SQLException异常的官方描述:
提供有关数据库访问错误或其他错误的信息的异常。每个SQLException都提供了几种信息:
1、 描述错误的字符串。这被用作Java异常消息,可通过getMesasge方法获得。
2、 一个“SQLstate”字符串。它遵循XOPEN SQLstate约定或SQL:2003约定。SQLState字符串的值在相应的规范中进行了描述。DatabaseMetaData方法getSQLStateType可用于发现驱动程序返回的是XOPEN类型还是SQL:2003类型。
3、 特定于每个供应商的整数错误代码。通常情况下,这将是底层数据库返回的实际错误代码。
4、 指向下一个异常的链。这可以用来提供额外的错误信息。
5、 该SQLException的因果关系(如果有的话)。

1、SQLWarning

SQLWarning (数据库访问警告)是SQLException的一个子类,用于表示有关数据库访问警告信息的异常,警告以静默方式链接到其方法导致其被报告的对象。

可以从Connection、Statement和ResultSet对象中检索警告,在连接关闭后尝试检索该连接上的警告将导致引发异常。类似地,试图在语句关闭后在语句上检索警告,或在结果集关闭后检索警告,都会引发异常。请注意,关闭一个语句也会关闭它可能产生的结果集。

需要注意的是,SQLWarning不会停止执行应用程序,而是提醒用户未正常按计划执行的一些事情。

1.1 DataTruncation

DataTruncation(数据超长截断) 是SQLWarning 的唯一一个子类。表示当数据长度由于超出字段最大长度限制而被意外截断 时,作为DataTruncation异常(写入时)引发的异常,或作为DataTrungation警告(读取时)报告的异常。

读取期间DataTruncation的 SQLstate为01004。
写入期间DataTruncation的 SQLstate为22001。

异常例图

异常分析
此异常一般出现在更新数据库时数据字段的长度超过了数据库的字段定义的长度。
需要注意的是,除了长度以外,精度、范围、大小等都有可能出现该异常。

2、RowSetWarning

RowSetWarning(行集警告)是SQLException的扩展,它提供有关在RowSet对象上设置的数据库警告的信息。警告以静默方式链接到其方法调用导致其被报告的对象,这个类补充了SQLWarning类。

可以从JdbcRowSet、CachedRowSet、WebRowSet、FilteredRowSet或JoinRowSet实现检索行集警告。
要检索在任何RowSet实现上报告的第一个警告,可使用在JdbcRowSet接口或CachedRowSet接口中定义的方法getRowSetWarnings。
要检索链接到第一个警告的警告,可使用RowSetWarning方法getNextWarning。
若要检索后续警告,可对返回的每个RowSetWarning对象调用getNextWarning。

3、BatchUpdateException

BatchUpdateException (批处理更新异常)表示在批处理更新操作期间发生错误。除了SQLException提供的信息外,BatchUpdateException还提供了在批更新期间成功执行的所有命令的更新计数,即在错误发生之前执行的所有指令。更新计数数组中元素的顺序与向批处理中添加命令的顺序相对应。

在批处理更新中的命令未能正确执行并引发BatchUpdateException之后,驱动程序可能会继续处理批处理中的剩余命令,也可能不会继续处理。如果驱动程序在失败后继续处理,则方法BatchUpdateException.getUpdateCounts返回的数组将为批处理中的每个命令都有一个元素,而不是仅为在错误发生前成功执行的命令有元素。在驱动程序继续处理命令的情况下,任何失败命令的数组元素都是Statement.EXECUTE_failed。

JDBC驱动程序实现应该使用构造函数BatchUpdateException(String reason、String SQLState、int vendorCode、long[]updateCounts、Throwable cause),而不是使用int[]作为更新计数的构造函数,以避免溢出的可能性。

如果调用Statement.exexecuteLargeBatch方法,建议调用getLargeUpdateCounts而不是getUpdateCounts,以避免整数更新计数可能溢出。

异常例图

异常分析

出现此异常信息,表示在批处理更新操作期间发生了错误,但具体原因有可能有多种情况,具体应该检查批处理的语句,包括以下几种情况:
1、查看语句涉及的数据字段长度是否超出了数据库字段所定义的长度大小
2、查看插入的字段名称是否与数据库的字段名是否一致
3、查看批处理是否有语法格式错误
4、批处理中是否出现了主键或联合主键冲突

4、SQLClientInfoException

当无法在连接上设置一个或多个客户端信息属性时,会引发SQLClientInfoException(设置客户端信息异常)
除了SQLException提供的信息外,SQLClientInfoException还提供了未设置的客户端信息属性的列表。有些数据库不允许以原子方式设置多个客户端信息属性,对于这些数据库,可能已经设置了一些客户端信息属性,即使Connection.setClientInfo方法抛出了异常。

应用程序可以使用getFailedProperties方法来检索未设置的客户端信息属性列表。通过将Map<String,ClientInfoStatus>传递到适当的SQLClientInfoException构造函数来标识属性。

5、SQLNonTransientException

当一个实例重试同一操作失败时抛出 SQLNonTransientException异常。

5.1 SQLInvalidAuthorizationSpecException

当SQLState类值为“28”或在供应商指定的条件下时,会引发 SQLInvalidAuthorizationSpecException(授权凭据无效异常),表示在建立连接期间提供的授权凭据无效

有关可能引发此异常的供应商指定条件,请参阅驱动程序供应商文档。

5.2 SQLDataException

当SQLState类值为“22”或在供应商指定的条件下时,会引发 SQLDataException(数据异常),表示各种数据错误,包括但不限于数据转换错误、除以0和函数的无效参数。

有关可能引发此异常的供应商指定条件,请参阅驱动程序供应商文档。

异常例图

异常分析
具体原因应该检查代码,包括以下几种情况:
1、实体类没有无参构造函数(可以用注解也可以手动添加无参构造函数)
2、数据字段格式不规范

5.3 SQLFeatureNotSupportedException

当SQLState类的值为 “0A”(值为“zero”A)时引发的SQLFeatureNotSupportedException(功能不支持异常)表明JDBC驱动程序不支持可选的JDBC功能

可选JDBC功能可以分为以下几类:
1、 不支持可选功能
2、 不支持可选的重载方法
3、 不支持方法的可选模式。方法的模式是根据作为参数值传递给方法的常数来确定的

5.4 SQLIntegrityConstraintViolationException

当SQLState类值为“23”或在供应商指定的条件下时,会引发 SQLIntegrityConstraintViolationException(违反完整性约束异常),表示违反了完整性约束(外键、主键或唯一键)

有关可能引发此异常的供应商指定条件,请参阅驱动程序供应商文档。

5.5 SQLSyntaxErrorException

当SQLState类值为“42”或在供应商指定的条件下时,会引发 SQLSyntaxErrorException(违反SQL语法异常),表示正在进行的查询违反了SQL语法规则

有关可能引发此异常的供应商指定条件,请参阅驱动程序供应商文档。

6、SQLRecoverableException

如果应用程序执行一些恢复步骤并重试整个事务,或者在分布式事务的情况下重试事务分支,则在以前失败的操作可能成功的情况下,可能抛出 SQLRecoverableException(恢复重试异常)。恢复操作至少必须包括关闭当前连接和获取新连接。

7、SQLTransientException

SQLTransientException(短暂性异常) 是在以前失败的操作可能能够成功的情况下抛出的。表示一个短暂性的异常,无需应用程序级功能的任何干预。

7.1 SQLTimeoutException

Statement.setQueryTimeout、DriverManager.setLoginTimeout、DataSource.setLoginTimeout、XADataSource.setLogonTimeout指定的超时时长已过期时,会引发SQLTimeoutException(sql执行超时异常),表示SQL执行超时。

7.2 SQLTransactionRollbackException

当SQLState类值为“40”或在供应商指定的条件下时,会引发SQLTransactionRollbackException(事务回滚异常),表示由于死锁或其他事务序列化失败,数据库自动回滚了当前语句

有关可能引发此异常的供应商指定条件,请参阅驱动程序供应商文档。

异常例图

异常分析
具体原因应该检查数据库及代码,包括以下几种情况:
1、查询是否有锁表情况导致回滚异常,可使用语句 show OPEN TABLES where In_use > 0,使用show processlist查询进程,可以把导致了锁表但能kill掉的进程kill掉;

8、SerialException

SerialException(序列化异常) 表示除DATALINK和JAVA OBJECT等SQL类型外,BLOB、CLOB、STRUCT或ARRAY等SQL类型的序列化或反序列化出错。

9、SyncFactoryException

SyncFactoryException (同步工厂异常)表示SyncFactory机制存在错误。如果未成功实例化SyncProvider,则无法使用断开连接的RowSet实现。

10、SyncProviderException

SyncProviderException 表示SyncProvider机制存在错误。如果SyncProvider抽象类扩展在读取或写入原始数据源时遇到冲突,则会出现此异常。

如果实现了这样做,SyncProvider对象也可以创建SyncResolver对象,并在构建时用它初始化SyncProviderException对象,或者在以后用SyncProvider对象设置它。

方法acceptChanges将在编写器完成冲突检查并发现一个或多个冲突后引发此异常。应用程序可以捕获SyncProviderException对象并调用其getSyncResolver方法来获取其SyncResolver对象。有关示例,请参阅SyncResolver接口注释中的代码片段。此SyncResolver对象将镜像生成异常的RowSet对象,但它将仅包含冲突的数据源中的值。SyncResolver对象中的所有其他值都将为null。

SyncResolver对象可用于检查和解决一行中的每个冲突,然后转到有冲突的下一行以重复该过程。
SyncProviderException对象可能包含也可能不包含导致异常的条件的描述。如果存在描述,则可以调用继承的方法getMessage来检索描述。

✔️ 一图总结

最后是异常体系之SQLException的脑图: