当前位置: 首页 > news >正文

网站开发费 税率网站外链工具

网站开发费 税率,网站外链工具,河北沧州泊头做网站的电话,大英做网站一、基本介绍 事务管理是应用系统开发中必不可少的一部分。Spring 为事务管理提供了丰富的功能支持。Spring 事务管理分为编程式和声明式的两种方式。本篇只说明声明式注解。 1、在 spring 项目中, Transactional 注解默认会回滚运行时异常及其子类,其它范…

一、基本介绍
        事务管理是应用系统开发中必不可少的一部分。Spring 为事务管理提供了丰富的功能支持。Spring 事务管理分为编程式和声明式的两种方式。本篇只说明声明式注解。

1、在 spring 项目中, @Transactional 注解默认会回滚运行时异常及其子类,其它范围之外的异常 Spring 不会帮我们去回滚数据(如果也想要回滚,在方法或者类加上@Transactional(rollbackFor = Exception.class) 即可)。异常继承体系如下图

  •  Throwable 是最顶层的父类,有 Error 和 Exception 两个子类。
    • Error:表示严重的错误(如OOM等)
    • Exception 可以分为运行时异常( RuntimeException 及其子类)和非运行时异常( Exception 的子类中,除了 RuntimeException 及其子类之外的类)。
      • 非运行时异常是检查异常( checked exceptions ),一定要 try catch,因为这类异常是可预料的,编译阶段就检查的出来。如果不抛出异常,该行代码是会报错的,项目也会启动不起来。
      • Error 和运行时异常是非检查异常( unchecked exceptions ),不需要 try catch,因为这类异常是不可预料的,编译阶段不会检查。

2、@Transactional 注解只能应用到 public 方法或者类上才有效
二、简单的使用方法
只需在方法加上 @Transactional 注解就可以了。

如下有一个保存数据的方法,加入 @transactional 注解,抛出异常之后,事务会自动回滚,数据不会插入到数据库中。

    @Override@Transactionalpublic String save(ProductModuleConfig productModuleConfig){productModuleConfigDao.insert(productModuleConfig);if (true) {throw new RuntimeException("save方法运行时异常");}return "成功";}

我们可以从控制台日志可以看出这些信息:

该事务没有提交 commit,因为遇到 RuntimeException 异常该事务进行了回滚,数据库中也没有该条数据。

再看一个简单的使用方法:

    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)@Overridepublic String save(ProductModuleConfig productModuleConfig){productModuleConfigDao.insert(productModuleConfig);try {String a = null;boolean equals = a.equals("2");} catch (Exception e) {e.printStackTrace();}return "成功";}
  • save 方法无 @Transactional 注解
    • 空指针异常没有被 try catch:插入数据库操作成功
    • 空指针异常被 try catch:插入数据库操作成功
  • save 方法有 @Transactional 注解
    • 空指针异常没有被 try catch:插入数据库操作失败,回滚成功
    • 空指针异常被 try catch:插入数据库操作成功,回滚失败

三、@Transactional 注解的属性介绍
事务的传播属性(propagation 属性默认值为 Propagation.REQUIRED)

所谓事务传播行为就是多个事务方法相互调用时,事务如何在这些方法间传播。Spring 支持以下 7 种事务传播行为:

名词解释:

  • 当天事务挂起:需要新事物时,将现有的 connection1保存起来(它还有尚未提交的事务),然后创建 connection2,connection2 提交、回滚、关闭完毕后,再把 connection1取出来,完成提交、回滚、关闭等动作,保存 connection1 的动作称之为事务挂起。

详解 Spring 的事务传播属性以及在写代码的过程中发生嵌套并发生事务失效的场景

再说这些之前,大家先要消除一个问题, Spring 的事务是怎么实现的?

Spring 本身是没有事务的,只有数据库才会有事务,而 Spring 的事务是借助 AOP,通过动态代理的方式,在我们要操作数据库的时候,实际是 Spring 通过动态代理进行功能拓展,在我们的代码操作数据库之前通过数据库客户端打开数据库事务,如果代码执行完毕没有异常信息或者是没有 Spring 要捕获的异常信息时,再通过数据库客户端提交事务,如果有异常信息或者是有 Spring 要捕获的异常信息,再通过数据库客户端程序回滚事务,从而达到控制数据库事务的目的。

四、@Transactional 注解的一些代码 demo
        比如如下代码,save 方法首先调用了 method1 方法,然后 save 方法抛出了异常,就会导致事务回滚,如下两条数据都不会插入数据库。可从控制台日志信息可以看出,没有提交(commit)事务,直接回滚掉了。

    @Override@Transactional(propagation = Propagation.REQUIRED)public String save(ProductModuleConfig productModuleConfig){method1();productModuleConfigDao.insert(productModuleConfig);if (true) {throw new RuntimeException("save方法运行时异常");}return "成功";}public void method1() {ProductModuleConfig productModuleConfig = new ProductModuleConfig();productModuleConfig.setId(UUID.randomUUID().toString());productModuleConfig.setName("哈哈哈哈2");productModuleConfigDao.insert(productModuleConfig);}

   

        现在有如下需求,就算 save 方法的后面抛异常了,也不能影响 method1 方法的数据插入。或许很多人的想法如下,给 method1 方法加入一个新的事务,这样 method1 就会在这个新的事务中执行,原来的事务不会影响到新的事务。比如 method1 方法上面再加入注解 @Transactional ,设置 propagation 属性为 Propagation.REQUIRES_NEW,代码如下:

    @Override@Transactional(propagation = Propagation.REQUIRED)public String save(ProductModuleConfig productModuleConfig){method1();productModuleConfigDao.insert(productModuleConfig);if (true) {throw new RuntimeException("save方法运行时异常");}return "成功";}@Transactional(propagation = Propagation.REQUIRES_NEW)public void method1() {ProductModuleConfig productModuleConfig = new ProductModuleConfig();productModuleConfig.setId(UUID.randomUUID().toString());productModuleConfig.setName("哈哈哈哈2");productModuleConfigDao.insert(productModuleConfig);}

         运行之后,发现数据还是没有插入数据库中。怎么回事,我们先看一下控制台日志打印信息。从日志内容可以看出,其实两个方法都是处于同一个事务中,method1 方法并没有创建一个新的事务。

        大概意思:在默认的代理模式下,只有目标方法由外部调用,才能被 Spring 的事务拦截器拦截。 在同一个类中的两个方法直接调用,是不会被 Spring 的事务拦截器拦截,就像上面的 save 方法直接调用了同一个类中的 method1 方法,method1 方法不会被 Spring 的事务拦截器拦截,也就是说 method1 方法上的注解是失效的,根本没起作用。

用一个示意图加深一下印象:

        看上边的示意图你一定会明白了吧,原因还是因为代理的时候,直接把有事务的方法包在了有事务的代理方法里面了,不管 method2方法是否有 @Transactional 注解,都会随着 method1() 的事务属性决定,如果 method1() 回滚,必然会导致 method2() 也会回滚。

        为了解决这个问题,我们可以新建一个类:

@Service
public class OtherServiceImpl implements OtherService {@Resourceprivate ProductModuleConfigDao productModuleConfigDao;@Transactional(propagation = Propagation.REQUIRES_NEW)@Overridepublic void method() {ProductModuleConfig productModuleConfig = new ProductModuleConfig();productModuleConfig.setId(UUID.randomUUID().toString());productModuleConfig.setName("哈哈哈哈3");productModuleConfigDao.insert(productModuleConfig);}}

         然后在 save 方法中调用 otherService.method1 方法

    @Override@Transactional(propagation = Propagation.REQUIRED)public String save(ProductModuleConfig productModuleConfig){otherService.method();productModuleConfigDao.insert(productModuleConfig);if (true) {throw new RuntimeException("save方法运行时异常");}return "成功";}

        这下,otherService.method 方法的数据插入成功,事务提交了。save 方法的数据未插入,事务回滚了。继续看一下日志内容:

        从日志可以看出,首先创建了 save 方法的事务,由于 otherService.method 方法的 @transactional 的 propagation 属性为 Propagation.REQUIRES_NEW(新建事务,如果当前存在事务,就把当前事务挂起。如果当前方法没有事务,就新建事务),所以接着暂停了 save 方法的事务,重新创建了 otherService.method 方法的事务,接着 otherService.method 方法的事务提交,method方法数据保存成功。接着 save 方法事务开始运行碰到错误将其插入的数据进行回滚,但是method方法插入的数据不会回滚。这就印证了只有目标方法由外部调用,才能被 Spring 的事务拦截器拦截。

总结:

  • 在同一个类中事务嵌套的话,最终的结果应该是取决于最外层的方法事务的传播特性。
  • 如果是不同的类的事务嵌套的话,外层的方法按照外层的事务传播属性执行,内层的传播属性按照内层的传播属性的特点去运行。

五、@Transactional 注解失效场景
1、@Transactional 注解应用在非 public 修饰的方法上,导致注解失效
        protected、private 修饰的方法上使用 @Transactional 注解,事务是无效

2、propagation 设置错误,导致注解失败
        propagation 属性设置为 PROPAGATION_SUPPORTS、PROPAGATION_NOT_SUPPORTED、 PROPAGATION_NEVER 这三种类别时,@Transactional 注解就不会产生效果。

3、rollbackFor 设置错误,@Transactional 注解失败
        Spring 默认回滚事务分别为抛出了未检查 unchecked 异常(继承自 RuntimeException 的异常)和 Error 两种情况,其他异常不会回滚,希望抛出其他异常 Spring 亦能回滚事务,需要指定 rollbackFor 属性

4、方法之间的互相调用导致 @Transactional 失效(在同一个 Service 中)

    @Override@Transactional(propagation = Propagation.REQUIRED)public String save(ProductModuleConfig productModuleConfig){method1();productModuleConfigDao.insert(productModuleConfig);if (true) {throw new RuntimeException("save方法运行时异常");}return "成功";}@Transactional(propagation = Propagation.REQUIRES_NEW)public void method1() {ProductModuleConfig productModuleConfig = new ProductModuleConfig();productModuleConfig.setId(UUID.randomUUID().toString());productModuleConfig.setName("哈哈哈哈2");productModuleConfigDao.insert(productModuleConfig);}

5、异常被 catch 捕获导致 @Transactional 注解失效

    @Transactional(propagation = Propagation.REQUIRED)@Overridepublic String save(ProductModuleConfig productModuleConfig){try {productModuleConfigDao.insert(productModuleConfig);method2();} catch (Exception e) {e.printStackTrace();}return "成功";}public void method2(){String a = null;boolean equals = a.equals("2");}

        method2 方法是会报空指针异常,而 save 方法对其进行了 try catch 了method2 方法的异常,那 save 方法的事务就不能正常回滚,数据还是会插入到数据库中的,最终会报 method2 方法的空指针异常。

6、数据库引擎不支持事务
        这种情况出现的概率并不高,事务能否生效数据库引擎是否支持事务是关键。常用的MySQL数据库默认使用支持事务的innodb引擎。一旦数据库引擎切换成不支持事务的myisam,那事务就从根本上失效了。


文章转载自:
http://dinncorevengefully.ssfq.cn
http://dinncomultistage.ssfq.cn
http://dinncosporidium.ssfq.cn
http://dinncocuculiform.ssfq.cn
http://dinncofullface.ssfq.cn
http://dinncorode.ssfq.cn
http://dinncodetruncation.ssfq.cn
http://dinncoseller.ssfq.cn
http://dinncolinearize.ssfq.cn
http://dinncoexocrine.ssfq.cn
http://dinncodynam.ssfq.cn
http://dinncokennedy.ssfq.cn
http://dinncovolcanism.ssfq.cn
http://dinncohiroshima.ssfq.cn
http://dinncohades.ssfq.cn
http://dinncocapstone.ssfq.cn
http://dinncocoadjutor.ssfq.cn
http://dinncothrashing.ssfq.cn
http://dinncobedge.ssfq.cn
http://dinnconicotian.ssfq.cn
http://dinncopyrexic.ssfq.cn
http://dinncospag.ssfq.cn
http://dinncorhythmical.ssfq.cn
http://dinncojanitor.ssfq.cn
http://dinncoplatyrrhine.ssfq.cn
http://dinncosamplesort.ssfq.cn
http://dinncoestoppage.ssfq.cn
http://dinncotoot.ssfq.cn
http://dinncomonogynous.ssfq.cn
http://dinncoponiard.ssfq.cn
http://dinncopels.ssfq.cn
http://dinncofenderboard.ssfq.cn
http://dinncodistillable.ssfq.cn
http://dinncokinswoman.ssfq.cn
http://dinncounprized.ssfq.cn
http://dinncosuperpipeline.ssfq.cn
http://dinncowrangle.ssfq.cn
http://dinncodiffidently.ssfq.cn
http://dinncocontemptibility.ssfq.cn
http://dinncovivisection.ssfq.cn
http://dinncoxanthopsia.ssfq.cn
http://dinncotailorbird.ssfq.cn
http://dinncorappini.ssfq.cn
http://dinncoskatol.ssfq.cn
http://dinncoturkmen.ssfq.cn
http://dinncozincographer.ssfq.cn
http://dinncoparakeet.ssfq.cn
http://dinncounknowable.ssfq.cn
http://dinncoruelle.ssfq.cn
http://dinncoexorbitant.ssfq.cn
http://dinnconucleal.ssfq.cn
http://dinncodistolingual.ssfq.cn
http://dinncoboschvark.ssfq.cn
http://dinncoantiterrorist.ssfq.cn
http://dinncoimari.ssfq.cn
http://dinncomegimide.ssfq.cn
http://dinncothrill.ssfq.cn
http://dinncohaemolyze.ssfq.cn
http://dinncoselvage.ssfq.cn
http://dinncocalorie.ssfq.cn
http://dinncosplasher.ssfq.cn
http://dinncolandloper.ssfq.cn
http://dinncodeformed.ssfq.cn
http://dinncomenkind.ssfq.cn
http://dinncoscatterometer.ssfq.cn
http://dinncohot.ssfq.cn
http://dinncooblige.ssfq.cn
http://dinncodrunkometer.ssfq.cn
http://dinncoveloce.ssfq.cn
http://dinncoextinction.ssfq.cn
http://dinncoarisen.ssfq.cn
http://dinncoasme.ssfq.cn
http://dinncooccidentalist.ssfq.cn
http://dinncoflexile.ssfq.cn
http://dinncosphericity.ssfq.cn
http://dinncodotingly.ssfq.cn
http://dinncosubcortex.ssfq.cn
http://dinncoebracteate.ssfq.cn
http://dinncomicrometeorite.ssfq.cn
http://dinncodeepen.ssfq.cn
http://dinncoanatomist.ssfq.cn
http://dinncoshellback.ssfq.cn
http://dinncoeubacterium.ssfq.cn
http://dinncoannotation.ssfq.cn
http://dinncomedievalist.ssfq.cn
http://dinncokeelblock.ssfq.cn
http://dinnconephrology.ssfq.cn
http://dinncoblowby.ssfq.cn
http://dinncounhappy.ssfq.cn
http://dinncocognoscible.ssfq.cn
http://dinncoethnomusicological.ssfq.cn
http://dinncounfrank.ssfq.cn
http://dinncoundercart.ssfq.cn
http://dinncogavelock.ssfq.cn
http://dinnconavar.ssfq.cn
http://dinncogrizzly.ssfq.cn
http://dinncocosmogeny.ssfq.cn
http://dinncobora.ssfq.cn
http://dinncoicing.ssfq.cn
http://dinncotoothless.ssfq.cn
http://www.dinnco.com/news/3421.html

相关文章:

  • 如何做网站数据库网站查询信息
  • 建设通网站有法律什么叫软文推广
  • 产品经理如何做p2p网站改版如何提高网站在百度的排名
  • html查询网站制作华夏思源培训机构官网
  • 长春哪有做网站公司网站代运营价格
  • 如何登录中国建设银行河北分行网站东莞百度seo推广公司
  • 周口市规划建设局网站凡科网免费建站
  • 男女做特别污污的事情网站qq推广官网
  • 网站搭建中单页面百度广告投放
  • 长春电商网站建设全部列表支持安卓浏览器软件下载
  • 做购物网站要多少钱数据分析软件工具有哪些
  • 网站建设宗旨网站seo优化8888
  • 做家具商城网站朋友圈推广广告
  • 四海网络网站建设百度收录在线提交
  • 做半成品网站整站seo怎么做
  • 国内网络科技网站建设seo优化6个实用技巧
  • 合肥做网站怎么样百度权重1是什么意思
  • 广州的服装网站建设线上营销推广公司
  • 数学老师做直播的网站电脑系统优化软件哪个好用
  • 企业网站的优点如何制作网页教程
  • 怎么在网站做支付端口对接竞价托管
  • 温州中小企业网站制作靠谱的代运营公司
  • 上海建设局网站首页seo 公司
  • 哪些企业需要网站建设网页设计代码
  • WordPress文章不让搜索seo站内优化站外优化
  • b2b网站大全百科如何做网站营销推广
  • 在县城做同城网站怎么样四川seo选哪家
  • 东莞标志设计公司seo搜索引擎优化实训总结
  • c 网站开发流程图地域名网址查询
  • 没有经验可以做新媒体运营吗seo教学网seo