事务传播机制/数据库异常解析——2016-8-13分享总结

一. 事务的传播机制/required 跟 required new 的使用与区别

基础回顾

1.1 事务的隔离级别

  ISOLATION_READ_UNCOMMITTED(读未提交)

  ISOLATION_READ_COMMITTED(读已提交)

  ISOLATION_REPEATABLE_READ(可重复读)

  ISOLATION_SERIALIZABLE(序列化)    

  ISOLATION_DEFAULT(使用数据库默认隔离级别)

1.2 脏读,不可重复读以及幻读

  脏读:一个事务读取到另一事务未提交的更新新据。

  不可重复读:在同一事务中,多次读取同一数据返回的结果有所不同。换句话说就是,后续读取可以读到另一事务已提交的更新数据。

  幻读:事务1正常查询一次,之后事务2插入满足事务1查询条件的新行,再次用事务1查询,得到多出来的数据。

1.3 事务的传播属性

  PROPAGATION_REQUIRED:  支持当前事务,没有则新建

  PROPAGATION_REQUIRESNEW:  新建事务,如果当前存在事务,把当前事务挂起

  PROPAGATION_SUPPORTS:支持当前事务,如果当前没有事务,就以非事务方式执行

  PROPAGATION_MANDATORY:支持当前事务,如果当前没有事务,就抛出异常

  PROPAGATION_NOT_SUPPORTED:以非事务方式执行,如果当前存在事务,就把当前事务挂起。也就是说业务方法不需要事务

  PROPAGATION_NEVER:以非事务方式执行,如果当前存在事务,则抛出异常。也就是说业务方法绝对不能在事务范围内执行

  PROPAGATION_NESTED:如果一个活动的事务存在,则运行在一个嵌套的事务中。 如果没有活动事务, 则按REQUIRED属性执行  

二. 事务的回滚及传播机制总结

  1. 首先要注意的是 spring 的默认回滚,roll-back = “runtimeException”,即 spring 只回滚接收到的运行时异常,对于其他异常则不回滚;

  源码解析:

/*** Handle a throwable, completing the transaction.* We may commit or roll back, depending on the configuration.* @param txInfo information about the current transaction* @param ex throwable encountered*/protected void completeTransactionAfterThrowing(TransactionInfo txInfo, Throwable ex) {if (txInfo != null && txInfo.hasTransaction()) {if (logger.isTraceEnabled()) {logger.trace("Completing transaction for [" + txInfo.getJoinpointIdentification() +"] after exception: " + ex);}if (txInfo.transactionAttribute.rollbackOn(ex)) {try {txInfo.getTransactionManager().rollback(txInfo.getTransactionStatus());}catch (TransactionSystemException ex2) {logger.error("Application exception overridden by rollback exception", ex);ex2.initApplicationException(ex);throw ex2;}
...

  注意上述有一段是 txInfo.transactionAttribute.rollbackOn(ex) 方法,跟进此方法:

/*** The default behavior is as with EJB: rollback on unchecked exception.* Additionally attempt to rollback on Error.* <p>This is consistent with TransactionTemplate's default behavior.*/public boolean rollbackOn(Throwable ex) {return (ex instanceof RuntimeException || ex instanceof Error);}

  所以,默认不修改的话,只回滚 RuntimeException 或者 Error

  2. 对此我们可以针对性的添加需要回滚的策略,或者直接显示设置 roll-back = “Exception”,即回滚所有异常;

  3. 需要注意的是:普通情况下,如果异常被 try-catch 处理了,并为进一步抛出异常,那么由于 spring 并未接受到异常, 所以也不会回滚;

   本周讨论补充知识:

  4. 异常分为 应用层抛出 的异常,以及 数据库 的异常,如果是前者,可以正常应用 spring 的事务传播规则,如果是后者,那么一旦发生,数据库端就已经放弃事务,也就没有回滚一说();

  例: int 10/0 为应用层的异常,可以正常回滚; insert 提交一个已存在的 唯一字段,那么数据库会报错,由于事务本身也是由 spring 告之数据库处理,这种情况下,由于 数据库已经放弃事务,那么 spring 层面也不能进行事务回滚;

  5. 正常情况下不会出现一个接口的 bean 进行嵌套调用,如果有,该情况下,由于代理类不再使用 spring 动态代理中的接口实现的方式,而是采用 cglib 的继承实现方式,同样也会导致传播失效;

  6. 事务的传播机制较为常用的为:required,required-new,support。讨论结果为 required-new 跟 required 相比,使用应较为谨慎,原因:同一事务粒度更细更可控,同时也能避免 嵌套事务 可能导致的复杂情况,当然,具体情况需要根据具体业务来定,比如本次讨论中的项目,由于每一次操作的对象都要及时被可能存在的另一进程知悉,这种情况下需要 required-new 来实时开启事务告之其他进程;

  查询总结过程中发现的其它知识点

  1. 注意的小点,MySQL 中 InnoDB 支持事务,MyIsam 并不支持事务;

  2. spring 已经提供了异常处理机制,其基类为 DataAccessException ,它是 RuntimeExcption 的一个子类,据此可以知道,所有从 数据库返回的异常,都会被 spring 处理后 归属于 RuntimeException 中,其体系如下:

  

2. 在 org.springframework.jdbc.support包下有sql-error-codes.xml文件,里面预定义了一些错误代码和信息,其 bean 为 HSQL,在 第8行,我们可以发现重复插入的 code 为 -104;

  bean id="HSQL" class="org.springframework.jdbc.support.SQLErrorCodes"    property name="databaseProductName"     valueHSQL Database Engine/value     /property     property name="badSqlGrammarCodes"     value-22,-28/value     /property     property name="duplicateKeyCodes"     value-104/value     /property     property name="dataIntegrityViolationCodes"     value-9/value     /property     property name="dataAccessResourceFailureCodes"     value-80/value     /property     /bean     

  3. 此外,我们可以知道发散性的看,我们完全可以自定义数据库异常的信息,方法如下:

  3.1 重新新建一个sql-error-codes.xml代码,并将它放到类路径的根目录下,这样Spring会发现它并使用我们自定义的文件。同时HSQL的bean的名称不要改,并将useSqlStateForTranslation置为false,就可以使用我们自己定义的异常类;

bean id="HSQL" class="org.springframework.jdbc.support.SQLErrorCodes"     property name="databaseProductName" value="HSQL Database Engine" /     property name="useSqlStateForTranslation" value="false" /     property name="customTranslations"     list     ref local="vehicleDuplicateKeyTranslation" /     /list     /property     /bean     
bean id="vehicleDuplicateKeyTranslation"     class="org.springframework.jdbc.support.CustomSQLErrorCodesTranslation"     property name="errorCodes" value="-104" /     property name="exceptionClass" value="org.ourpioneer.vehicle.exception.VehicleDuplicateKeyException" /     /bean 

  3.2 可以看到结果,控制台所打印的异常类型为我们自己定义的异常类型;

  3.3 除此之外,还可以实现SQLExceptionTranslator接口,并在JDBC模板中注入其实例来实现异常控制

   1. package org.ourpioneer.vehicle.exception;      2. import java.sql.SQLException;      3. import org.springframework.dao.DataAccessException;      4. import org.springframework.jdbc.UncategorizedSQLException;      5. import org.springframework.jdbc.support.SQLExceptionTranslator;      6. public class VehicleDuplicateKeyTranslator implements SQLExceptionTranslator {      7.     public DataAccessException translate(String task, String sql,      8.             SQLException ex) {      9.         if (task == null) {      10.             task = "";      11.         }      12.         if (sql == null) {      13.         }      14.         if (ex.getErrorCode() == -104) {      15.             return new VehicleDuplicateKeyException(buildMessage(task, sql, ex));      16.         } else {      17.             return new UncategorizedSQLException(task, sql, ex);      18.         }      19.     }      20.     private String buildMessage(String task, String sql, SQLException ex) {      21.         return "数据库操作异常:" + task + "; SQL [" + sql + "]; " + ex.getMessage();      22.     }      23. } 

  3.4 translate方法有三个参数,task表示当前操作要进行的任务是什么,sql就是执行的sql语句,ex表示SQLException,我们可以从中获取异常信息,其处理代码仅仅捕捉了错误码为-104(HSQL数据库)的错误,其余的配置信息可以根据需要来自行添加。之后要在Spring中重新配置它们:

   1. bean id="vehicleDuplicateKeyTranslator"     2. class="org.ourpioneer.vehicle.exception.VehicleDuplicateKeyTranslator"/bean     3. bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"     4.     property name="exceptionTranslator" ref="vehicleDuplicateKeyTranslator" /     5.     property name="dataSource" ref="dataSource" /     6. /bean     7. bean id="vehicleDAO" class="org.ourpioneer.vehicle.dao.VehicleDAOImpl"     8.     property name="jdbcTemplate" ref="jdbcTemplate" /     9. /bean 

  3.5 测试结果

 

三. 总结

  其实之前对事务的理解是比较基础的,经过周六的交流和学习,才对事务有了略深一层的理解,但同时也愈发觉得事务的博大精深应远不止于此,本文大部分都是结合各位?同事的理解和网上的一些资料整理的文章,所以本文作用更多的督促自己的学习进步,希望以后自己能不断的吸收,整理和提炼知识?。

 

参考文献:

mysql隔离级别及事务传播:https://gist.github.com/JagoWang/4555317

mysql事务管理及spring声明式事务中主动异常抛出使数据库回滚:http://www.cnblogs.com/wanglonghai/p/4866512.html

Spring访问数据库异常的处理方法:http://kb.cnblogs.com/page/89216/

转载于:https://www.cnblogs.com/Mr-Persist/p/5773314.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/254677.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

20155307 2016-2017 《Java程序设计》第三次实验报告

&#xff08;一&#xff09;敏捷开发与XP 敏捷开发是一种以人为核心、迭代、循序渐进的开发方法。“敏捷流程”是一系列价值观和方法论的集合。从2001年开始&#xff0c;一些软件界的专家开始倡导“敏捷”的价值观和流程&#xff0c;他们肯定了流行做法的价值&#xff0c;但是强…

ElasticSearch创建、修改、获取、删除、索引Indice mapping和Index Template案例

为什么80%的码农都做不了架构师&#xff1f;>>> The best elasticsearch highlevel java rest api-----bboss ElasticSearch客户端框架bboss的ClientInterface 接口提供了创建/修改、获取、删除索引Indice和IndexTemplate的方法&#xff0c;本文举例说明其使用方法…

spring mvc注解@RequestMapping

1、url路径映射 基本功能 2、窄化请求映射 根路径子路径 注意setViewName的路径。 3、限制http请求方法 get和 post 如果是get 转载于:https://www.cnblogs.com/jway1101/p/5773923.html

老婆的驾照要下来了,形容下我此刻的心情

&#xfeff;&#xfeff; 老婆的驾照要下来了&#xff0c;形容下我此刻的心情&#xff1a; 路上遇到的女人&#xff0c;大部分是不用眼睛和脑子开车的&#xff0c;完全是凭自己的感觉开车。凡是看到前车奇慢、路口犹豫不决、不打灯缓慢变线、不该…

windows环境下OpenLDAP安装与客户端连接配置

2019独角兽企业重金招聘Python工程师标准>>> 1.下载安装OpenLDAP版本 C:\Users\Administrator>slapd -V OpenLDAP 2.4.42 Standalone LDAP Server (slapd) 2.安装过程中&#xff0c;全部用默认的操作执行即可。 3.修改OpenLDAP文件如下&#xff1a; # MDB Backen…

halcon标定后改变世界坐标系参考点方法

halcon相机标定完成后&#xff0c;世界坐标系原点在标定板的中间&#xff0c;如果要自定义坐标系原点该如何操作 如图&#xff1a; 方法1 使用仿射变换 *pose_to_hom_mat3d (FinalPose, HomMat3D) *hom_mat3d_translate_local (HomMat3D, dx, dy, 0, HomMat3DTranslate) *hom_…

KUKA---US2电源的安全属性-------老款硬线连接实现的DRIVE安全STO SBC 、新款基于Safety over EtherCAT 网络帧实现的DRIVE安全STO SBC

安全双回路的监控&#xff1a;&#xff08;工业上的安全&#xff0c;是指安全等级&#xff0c;没有绝对的安全&#xff09; 1. 机械式&#xff1a;监控关断继电器的辅助反馈触点&#xff0c;这个关断继电器包含机械联锁触点&#xff0c;这样反馈触点和主触点可以同步开关动…

X11硬线接口信号 与Profisafe安全输入输出信号之间的区别与比较

&#xfeff;&#xfeff;X11硬线接口信号 与Profisafe安全输入输出信号之间的区别与比较 Profisafe安全输入信号US2信号有待深入&#xff08;通过外部PLC &#xff1a;&#xff09; &#xfeff;&#xfeff;

var类型推断关键字

目录var 类型推断介绍var的一个例子&#xff1a;编程遵循规则var 类型推断介绍 使用var定义变量时&#xff0c;用var关键字替代实际类型。编译器可以根据变量的初始化值自行“推断”变量的类型。 例如&#xff1a; var A 0&#xff1b; 等价于 int A 0&#xff1b;var的一个…

斯坦福大学机器学习——高斯判别分析

转自 http://blog.csdn.net/linkin1005/article/details/39054023 同朴素贝叶斯一样&#xff0c;高斯判别分析&#xff08;Gaussian discriminant analysismodel, GDA&#xff09;也是一种生成学习算法&#xff0c;在该模型中&#xff0c;我们假设y给定的情况下&#xff0c;x服…

MapGIS转Shp文件的单位问题

MapGIS转Shp文件的单位问题 原文:MapGIS转Shp文件的单位问题在MapGIS浏览查看一下数据&#xff0c;各种不习惯&#xff1b;用mapgis自带的转shp功能&#xff0c;属性表会出错&#xff1b;利用名为map2shp的试用版软件可将mapgis格式的数据较为良好转成shp格式。但经常会遇到一个…

显示/隐藏Mac系统中所有的隐藏文件

显示&#xff1a; 在终端输入:defaults write com.apple.finder AppleShowAllFiles YES隐藏: 在终端输入:defaults write com.apple.finder AppleShowAllFiles NO然后重启Finder即可(先点击左上角的苹果图标&#xff0c;再选强制退出&#xff0c;然后选中Finder&#xff0c;点击…

机械零点、MAM 文件 、 EMT标定原理

&#xfeff;&#xfeff; 机械零点、MAM 文件、EMT标定原理。 可调节的机械零点&#xff0c;不需要MAM文件&#xff0c;使之成为90度。 不可调节的机械零点&#xff0c;需要MAM文件修正&#xff0c;使之成为90度。 带负载的偏移补偿、带负载的偏移补偿mastering。做过带负…

智慧城市的互联网大脑架构图:大社交网络与智慧城市结合是关键

从本质上讲智慧地球和智慧城市还是互联网发展到一定程度&#xff0c;向城市建设蔓延和深入的结果。因此建设智慧城市就不能不忽略互联网的发展趋势和进化规律。 而越来越多的迹象表明“互联网正在向着与人类大脑高度相似的方向进化&#xff0c;它将具备自己的视觉、听觉、触觉、…

20145227鄢曼君《网络对抗》Web安全基础实践

20145227鄢曼君《网络对抗》Web安全基础实践 实验后回答问题 1.SQL注入攻击原理&#xff0c;如何防御&#xff1f; SQL注入攻击指的是通过构建特殊的输入作为参数传入Web应用程序&#xff0c;而这些输入大都是SQL语法里的一些组合&#xff0c;通过执行SQL语句进而执行攻击者所要…

[转]Xvid参数详解

众所周知&#xff0c;Mencoder以其极高的压缩速率和不错的画质赢得了很多朋友的认同&#xff01; 原来用Mencoder压缩Xvid的AVI都是使用Xvid编码器的默认设置&#xff0c;现在我来给大家冲冲电&#xff0c;讲解一下怎样使用Mencoder命令行高级参数制作Xvid编码格式AVI影片。经…

关于box-shadow属性的一点心得

一般我用到box-shadow都是用于诸如按钮&#xff0c;文本块&#xff0c;某些图标&#xff0c;css类似为: box-shadow: 1px 1px 5px rgba(0, 0, 0, .8);这样&#xff0c;样式看上去会更加柔和&#xff0c;或者增加了立体感。 我个人的理解上&#xff0c;box-shadow的本质就是本体…

javascript:正则表达式、一个表单验证的例子

阅读目录 本文内容&#xff1a;正则表达式&#xff1a;利用正则表达式进行表单验证的例子&#xff1a;回到顶部本文内容&#xff1a; 正则表达式正则表达式的使用方法正则表达式的特殊匹配字符正则表达式修饰符利用正则表达式进行表单验证的例子首发日期&#xff1a;2018-05-13…

Spring_01 spring容器、控制反转(IOC)、依赖注入(DI)

目录 1 什么是spring框架 2 spring框架的特点 3 spring容器 3.1 什么是spring容器 3.2 spring容器创建对象的编程步骤 3.4 spring容器创建对象的方式 3.5 bean元素的几个重要属性 4 IOC 4.1 什么是IOC 4.2 什么事DI 4.3 DI的三种方式 1 什么是spring框架 是一个开源的用来简化企…