前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Spring事务异常回滚需要数据库引擎支持

Spring事务异常回滚需要数据库引擎支持

作者头像
似水的流年
发布2019-12-05 18:49:11
8880
发布2019-12-05 18:49:11
举报
文章被收录于专栏:电光石火电光石火

例:一个方法报异常,另一个方法不会回滚

代码语言:javascript
复制
try {
userDao.save(user);
userCapabilityQuotaDao.save(capabilityQuota);
} catch (Exception e) {
}

例:一个方法报异常,另一个方法回滚 在catch语句中最后增加throw new RuntimeException()语句,以便让aop捕获异常再去回滚,并且在service上层(webservice客户端,view层action)要继续捕获这个异常并处理

代码语言:javascript
复制
try {
userDao.save(user);
userCapabilityQuotaDao.save(capabilityQuota);
} catch (Exception e) {
throw new RuntimeException();
}

【现在的做法】在service层方法的catch语句中增加:TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();语句,手动回滚,这样上层就无需去处理异常了

代码语言:javascript
复制
try {
userDao.save(user);
userCapabilityQuotaDao.save(capabilityQuota);
} catch (Exception e) {
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
}

其实像第一种try catch这种把整个包裹起来,这种业务方法也就等于脱离了spring事务的管理,因为没有任何异常会从业务方法中抛出,全被捕获并“吞掉”,导致spring异常抛出触发事务回滚策略失效。 如果在catch代码块中采用页面硬编码的方式使用spring api对事务做显式的回滚,这样写也是可以的。

异常的一些基本知识 异常的架构 异常的继承结构:Throwable为基类,Error和Exception继承Throwable。Error和RuntimeException及其子类成为未检查异常(unchecked),其它异常成为已检查异常(checked)。

805308-20170407134736253-1566741718.jpg
805308-20170407134736253-1566741718.jpg

Error异常 Error表示程序在运行期间出现了十分严重、不可恢复的错误,在这种情况下应用程序只能中止运行,例如JAVA 虚拟机出现错误。Error是一种unchecked Exception,编译器不会检查Error是否被处理,在程序中不用捕获Error类型的异常。一般情况下,在程序中也不应该抛出Error类型的异常。 RuntimeException异常 Exception异常包括RuntimeException异常和其他非RuntimeException的异常。 RuntimeException 是一种Unchecked Exception,即表示编译器不会检查程序是否对RuntimeException作了处理,在程序中不必捕获RuntimException类型的异常,也不必在方法体声明抛出 RuntimeException类。RuntimeException发生的时候,表示程序中出现了编程错误,所以应该找出错误修改程序,而不是去捕获RuntimeException。 Checked Exception异常 Checked Exception异常,这也是在编程中使用最多的Exception,所有继承自Exception并且不是RuntimeException的异常都是checked Exception,上图中的IOException和ClassNotFoundException。JAVA 语言规定必须对checked Exception作处理,编译器会对此作检查,要么在方法体中声明抛出checked Exception,要么使用catch语句捕获checked Exception进行处理,不然不能通过编译。

代码语言:javascript
复制
a、注解方式。   @javax.transaction.Transactional 和 @org.springframework.transaction.annotation.Transactional 相似,均可使用。
rollbackFor定义的是需要回滚的异常,noRollbackFor定义的是不需要回滚的异常。(默认情况下对Error和RuntimeException及其子类进行回滚)

@Transactional(rollbackFor=MyException.class,noRollbackFor=OtherException.class)
public void updateUser(User user){
  dao.update(user);
}
代码语言:javascript
复制
b、配置方式。   定义时声明类的全限定名







注:若rollbackFor和noRollbackFor配置的类相同,则出现对应异常会进行回滚
代码语言:javascript
复制
c、若需要自行捕获异常进行处理,则使用 TransactionAspectSupport.currentTransactionStatus().setRollbackOnly() 语句进行手动回滚。

@Transactional(rollbackFor=MyException.class,noRollbackFor=RuntimeException.class)
public void updateUser(User user){
    try{
        dao.update(user);
    }catch(MyException e){
        //------//其他操作
        TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();//捕获异常后进行回滚
    }
}

注意数据库引擎问题

851461-20170306202857781-1607368004.png
851461-20170306202857781-1607368004.png

InnoDB:支持事务处理,支持外键,支持崩溃修复能力和并发控制。如果需要对事务的完整性要求比较高(比如银行),要求实现并发控制(比如售票),那选择InnoDB有很大的优势。如果需要频繁的更新、删除操作的数据库,也可以选择InnoDB,因为支持事务的提交(commit)和回滚(rollback)。 MyISAM:插入数据快,空间和内存使用比较低。如果表主要是用于插入新记录和读出记录,那么选择MyISAM能实现处理高效率。如果应用的完整性、并发性要求比 较低,也可以使用。 MEMORY:所有的数据都在内存中,数据的处理速度快,但是安全性不高。如果需要很快的读写速度,对数据的安全性要求较低,可以选择MEMOEY。它对表的大小有要求,不能建立太大的表。所以,这类数据库只使用在相对较小的数据库表。 注意,同一个数据库也可以使用多种存储引擎的表。如果一个表要求比较高的事务处理,可以选择InnoDB。这个数据库中可以将查询要求比较高的表选择MyISAM存储。如果该数据库需要一个用于查询的临时表,可以选择MEMORY存储引擎。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018-10-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云数据库 SQL Server
腾讯云数据库 SQL Server (TencentDB for SQL Server)是业界最常用的商用数据库之一,对基于 Windows 架构的应用程序具有完美的支持。TencentDB for SQL Server 拥有微软正版授权,可持续为用户提供最新的功能,避免未授权使用软件的风险。具有即开即用、稳定可靠、安全运行、弹性扩缩等特点。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档