升级 iBATIS/MyBATIS 对处理 DuplicateKeyException 的影响
source link: https://www.diguage.com/post/upgrade-ibatis-mybatis-about-duplicate-key-exception/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
升级 iBATIS/MyBATIS 对处理 DuplicateKeyException 的影响
在 关于升级 Spring 等依赖的一些经验 中,分享了一些开源依赖的升级经验。部分小伙伴质疑升级 iBATIS/MyBATIS 会影响对 DuplicateKeyException
异常的处理。这篇文章就从源码分析/代码更新的就角度来分析一下升级相关依赖是否会对 DuplicateKeyException
异常的处理带来实质性的影响。
由于主要的技术栈涉及 MySQL 驱动、iBATIS、MyBATIS、Spring 周边等。所以,本文仅分析涉及的这些依赖。
D瓜哥使用 MySQL: Employees Sample Database 搭建了一个 Spring + MyBATIS + MySQL Connector/J 的测试环境。连续插入两条一样的数据,单步调试,在 com.mysql.jdbc.MysqlIO#sendCommand
方法中,就可以观察到如下异常:
从这里可以明显看出,MySQL 驱动返回的异常中, venderCode
编码是 1062
。
顺着这个线,往上走,到 org.apache.ibatis.session.defaults.DefaultSqlSession#update(java.lang.String, java.lang.Object)
方法中,可以看到,
在这里,会将 SQLException
包装成 PersistenceException
,这也是 MyBATIS 对外暴露的统一的异常类。
继续往上走,就到了 org.mybatis.spring.SqlSessionTemplate.SqlSessionInterceptor#invoke
方法:
在 SqlSessionInterceptor#invoke
方法的异常处理中,将 PersistenceException
异常通过 org.springframework.dao.support.PersistenceExceptionTranslator#translateExceptionIfPossible
方法,将异常转换成 DataAccessException
对象。 DataAccessException
类是 Spring 数据访问的异常类基类。
这里还会牵扯到 SQLExceptionTranslator
类。代码一路跟踪下去,最后,会发现是在 org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator#doTranslate
中完成了转换工作:
请注意这里的类名: SQLErrorCodeSQLExceptionTranslator
,见名知意,类名明确地说明,是通过错误编码来确定具体异常类的。
这里再看一看异常信息的生成方法:
这里一眼就可以看出,Spring 生成 DataAccessException
对象的错误信息时,是通过在 SQLException
错误信息基础上,在前面加上了 SQL 信息。
可以在 spring-jdbc.jar!/org/springframework/jdbc/support/sql-error-codes.xml
中查看到 Spring 内置支持的所有数据库类型以及对应的错误编码。关于 MySQL 的配置如下:
在 MySQL Connector/J release/5.1 中可以下载到 MySQL 驱动的代码。其中,在 com.mysql.jdbc.MysqlErrorNumbers#ER_TRG_CORRUPTED_FILE
可以查看到 1602
错误的定义。查看代码变更历史,这个编码从 2011 年增加到这个文件中的。
再回过头来看 Spring 中 sql-error-codes.xml
的代码变更历史,其中可以看到 MySQL 1602
是在 2009-03-10
加入到配置文件中的。而 Spring 3.x 版的第一个版本 3.0.0.RELEASE
是在 2009年12月17日发布的。所以,从 Spring 3.0.0.RELEASE 开始,Spring 对 MySQL 数据库异常的处理,几乎保持不变。
最后,再看一下 iBATIS 的异常处理。 iBATIS 的异常处理比较简单,代码都集中在 org.springframework.orm.ibatis.SqlMapClientTemplate
(该代码已经从 Spring 4 开始从 Spring 仓库中删除) 中:
这里也是通过基类 org.springframework.jdbc.support.JdbcAccessor
的 getExceptionTranslator
方法,获取 SQLExceptionTranslator
对象,然后调用其 translate
方法来完成异常转换,和上面 MyBATIS 中的处理逻辑是一样的。
综上,升级 iBATIS/MyBATIS 不会对 DuplicateKeyException
异常的处理有任何影响,可以放心升级。
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK