草庐IT

Spring的事务控制

幽默涵养miss u 2023-07-27 原文

一、声明式事务

(1)场景:

在Spring整个Mybatis后,默认是每个sql语句看作一个事务,当我们有业务需要多条sql时我们就需要控制事务了。

(2)原理:

声明式事务是基于AOP实现的。程序员只需要编写调用持久层代码和业务逻辑代码。把开启事务的代码放在前置通知中,把事务回滚和事务提交的代码放在了后置通知中

(3)使用方式:

1.导入spring-tx

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-tx</artifactId>
    <version>5.3.23</version>
</dependency>

2. 在applicationContext.xml中配置三个标签


    <bean class="org.springframework.jdbc.datasource.DataSourceTransactionManager" id="txManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <!-- 配置通知,细化哪些方法需要进行哪些事务管理 -->
    <tx:advice transaction-manager="txManager" id="txAdvice">
        <tx:attributes>
            <!--
                name:配置哪些方法有事务控制
                read-only:是否是只读业务,表示不使用事务控制,也代表查询
                rollback-for:表示出现什么类型的异常进行数据回滚
                no-rollback-for:当出现什么异常的时候不进行数据回滚 
            -->
            <tx:method name="*"/>
        </tx:attributes>
    </tx:advice>

    <aop:config proxy-target-class="true">
        <aop:pointcut id="mypoints" expression="execution(* com.bjsxt.service.impl.*.*(..))"/>
        <aop:advisor advice-ref="txAdvice" pointcut-ref="mypoints"/>
    </aop:config>

 (4)使用注解的方式

1.配置注解扫描

<context:component-scan base-package="com.bjsxt.service.impl"></context:component-scan>

2.开启事务注解的支持

<tx:annotation-driven></tx:annotation-driven>

3.配置事务管理器类

 <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"></property>
    </bean>

4.@Transactional //在方法或者类上使用简单注解就可以

二、spring中的软编码

(1)在applicationContext.xml中引入配置文件

<context:property-placeholder location="classpath:jdbc.properties"/>

(2)在applicationContext.xml可以通过${key}的方式获取value,也可以在spring容器中的类中通过@Value("${key}")注解给属性赋value值。

三、事务的隔离级别

(1)事务问题

多个事务同时操作数据库时,允许多个事务操作的方式就是事务隔离级别。事务隔离级别主要是通过添加锁操作实现的。事务隔离级别主要是解决高并发下脏读、幻读、不可重复读问题的。

脏读:

事务A没有提交事务,事务B读取到事务A未提交的数据,这个过程称为脏读。读取到的数据叫做脏数据。

不可重复读:

当事务A读取到表中一行数据时,同时另一个事务修改这行数据,事务A读取到的数据和表中真实数据不一致。 ​

幻读:

事务A对表做查询全部操作,事务B向表中新增一条数据。事务A查询出来的数据和表中数据不一致,称为幻读。

(2)spring中如何解决

我们可以在tx:method或@Transactional中设置属性isolation的值来进行配置,isolation可取值有

DEFAULT:

表示用数据库的隔离级别,MySQL8默认的事务隔离级别

REPEATABLE_READ (select @@transaction_isolation)

READ_UNCOMMITTED:

读未提交(脏读,幻读,不可重复读)

READ_COMMITTED:

读已提交(幻读,不可重复读)

REPEATABLE_READ:

可重复读(幻读)

SERIALIZABLE

串行读来通过牺牲性能解决脏读、不可重复度、幻读问题。

三、事务的传播行为

(1)问题

service方法相互调用时,每个方法都是单独的事务,但是我们不希望这样,就研究出了事务的传播行为。

spring默认的事务传播行为:当一个被声明式事务管理的方法,调用另一个声明式事务管理的方法时,如果在调用另一个方法时发现当前已经有事务了,则加入事务,如果没有事务,开启事务。

(2)spring中控制事务的传播行为

可以通过进行配置tx:method或@Transactional中的propagation属性来进行设置,propagation属性的可选值有:

REQUIRED:默认值。如果当前有事务则加入到事务中。如果当前没有事务则新增事务。

NEVER:必须在非事务状态下执行,如果当前没有事务,正常执行,如果当前有事务,报错.

NESTED:必须在事务状态下执行.如果没有事务,新建事务,如果当前有事务,创建一个嵌套事务,mysql中当父事务回滚时,会自动让子事务也回滚。

REQUIRES_NEW:必须在事务中执行,如果当前没有事务,新建事务,如果当前有事务,把当前事务挂起. 在重新建 个事务。(调用者统一提交回滚)

SUPPORTS:如果当前有事务就在事务中执行,如果当前没有事务,就在非事务状态下执行.

NOT_SUPPORTED:必须在非事务下执行,如果当前没有事务,正常执行,如果当前有事务,把当前事务挂起.

MANDATORY:必须在事务内部执行,如果当前有事务,就在事务中执行,如果没有事务,报错.(可以配置在入口方法)

四、bean的生命周期

在这种情况下只会调用类的构造方法进行实例化。可以通过标签的init-method和destory-method自定义初始化和销毁方法。除此以外还可以让类实现各种Aware接口,例如BeanNameAware、BeanFactoryAware、ApplicationContextAware等。也可以通过InitializingBean,DisposableBean实例化Bean和销毁Bean。也可以通过BeanPostProcessor进行增强。但是当前类不能实现这个接口,且不能与BeanFactoryPostProcessor同时存在。

有关Spring的事务控制的更多相关文章

  1. Ruby Readline 在向上箭头上使控制台崩溃 - 2

    当我在Rails控制台中按向上或向左箭头时,出现此错误:irb(main):001:0>/Users/me/.rvm/gems/ruby-2.0.0-p247/gems/rb-readline-0.4.2/lib/rbreadline.rb:4269:in`blockin_rl_dispatch_subseq':invalidbytesequenceinUTF-8(ArgumentError)我使用rvm来管理我的ruby​​安装。我正在使用=>ruby-2.0.0-p247[x86_64]我使用bundle来管理我的gem,并且我有rb-readline(0.4.2)(人们推荐的最少

  2. ruby - 我可以使用 aws-sdk-ruby 在 AWS S3 上使用事务性文件删除/上传吗? - 2

    我发现ActiveRecord::Base.transaction在复杂方法中非常有效。我想知道是否可以在如下事务中从AWSS3上传/删除文件:S3Object.transactiondo#writeintofiles#raiseanexceptionend引发异常后,每个操作都应在S3上回滚。S3Object这可能吗?? 最佳答案 虽然S3API具有批量删除功能,但它不支持事务,因为每个删除操作都可以独立于其他操作成功/失败。该API不提供任何批量上传功能(通过PUT或POST),因此每个上传操作都是通过一个独立的API调用完成的

  3. ruby-on-rails - 带 Spring 锁的 Rails 4 控制台 - 2

    我正在使用Ruby2.1.1和Rails4.1.0.rc1。当执行railsc时,它被锁定了。使用Ctrl-C停止,我得到以下错误日志:~/.rvm/gems/ruby-2.1.1/gems/spring-1.1.2/lib/spring/client/run.rb:47:in`gets':Interruptfrom~/.rvm/gems/ruby-2.1.1/gems/spring-1.1.2/lib/spring/client/run.rb:47:in`verify_server_version'from~/.rvm/gems/ruby-2.1.1/gems/spring-1.1.

  4. ruby-on-rails - openshift 上的 rails 控制台 - 2

    我将我的Rails应用程序部署到OpenShift,它运行良好,但我无法在生产服务器上运行“Rails控制台”。它给了我这个错误。我该如何解决这个问题?我尝试更新ruby​​gems,但它也给出了权限被拒绝的错误,我也无法做到。railsc错误:Warning:You'reusingRubygems1.8.24withSpring.UpgradetoatleastRubygems2.1.0andrun`gempristine--all`forbetterstartupperformance./opt/rh/ruby193/root/usr/share/rubygems/rubygems

  5. ruby - 分布式事务和队列,ruby,erlang,scala - 2

    我有一个涉及多台机器、消息队列和事务的问题。因此,例如用户点击网页,点击将消息发送到另一台机器,该机器将付款添加到用户的帐户。每秒可能有数千次点击。事务的所有方面都应该是容错的。我以前从未遇到过这样的事情,但一些阅读表明这是一个众所周知的问题。所以我的问题。我假设安全的方法是使用两阶段提交,但协议(protocol)是阻塞的,所以我不会获得所需的性能,我是否正确?我通常写Ruby,但似乎Redis之类的数据库和Rescue、RabbitMQ等消息队列系统对我的帮助不大——即使我实现某种两阶段提交,如果Redis崩溃,数据也会丢失,因为它本质上只是内存。所有这些让我开始关注erlang和

  6. C51单片机——实现用独立按键控制LED亮灭(调用函数篇) - 2

    说在前面这部分我本来是合为一篇来写的,因为目的是一样的,都是通过独立按键来控制LED闪灭本质上是起到开关的作用,即调用函数和中断函数。但是写一篇太累了,我还是决定分为两篇写,这篇是调用函数篇。在本篇中你主要看到这些东西!!!1.调用函数的方法(主要讲语法和格式)2.独立按键如何控制LED亮灭3.程序中的一些细节(软件消抖等)1.调用函数的方法思路还是比较清晰地,就是通过按下按键来控制LED闪灭,即每按下一次,LED取反一次。重要的是,把按键与LED联系在一起。我打算用K1来作为开关,看了一下开发板原理图,K1连接的是单片机的P31口,当按下K1时,P31是与GND相连的,也就是说,当我按下去时

  7. spring.profiles.active和spring.profiles.include的使用及区别说明 - 2

    转自:spring.profiles.active和spring.profiles.include的使用及区别说明下文笔者讲述spring.profiles.active和spring.profiles.include的区别简介说明,如下所示我们都知道,在日常开发中,开发|测试|生产环境都拥有不同的配置信息如:jdbc地址、ip、端口等此时为了避免每次都修改全部信息,我们则可以采用以上的属性处理此类异常spring.profiles.active属性例:配置文件,可使用以下方式定义application-${profile}.properties开发环境配置文件:application-dev

  8. ruby-on-rails - 在 Rails 控制台中使用 asset_path - 2

    在我的Character模型中,我添加了:字符.rbbefore_savedoself.profile_picture_url=asset_path('icon.png')end但是,对于数据库中已存在的所有角色,它们的profile_picture_url为nil。因此,我想进入控制台并遍历所有这些并进行设置。在我试过的控制台中:Character.find_eachdo|c|c.profile_picture_url=asset_path('icon.png')end但这给出了错误:NoMethodError:undefinedmethod`asset_path'formain:O

  9. ruby-on-rails - 带有 Pry 的 Rails 控制台 - 2

    当我进入Rails控制台时,我已将pry设置为加载代替irb。我找不到该页面或不记得如何将其恢复为默认行为,因为它似乎干扰了我的Rubymine调试器。有什么建议吗? 最佳答案 我刚发现问题,pry-railsgem。忘记了它的目的是让“railsconsole”打开pry。 关于ruby-on-rails-带有Pry的Rails控制台,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/question

  10. ruby - 将全局 $stdout 重新分配给控制台 - ruby - 2

    我正在尝试将$stdout设置为临时写入一个文件,然后返回到一个文件。test.rb:old_stdout=$stdout$stdout.reopen("mytestfile.out",'w+')puts"thisgoesinmytestfile"$stdout=old_stdoutputs"thisshouldbeontheconsole"$stdout.reopen("mytestfile1.out",'w+')puts"thisgoesinmytestfile1:"$stdout=old_stdoutputs"thisshouldbebackontheconsole"这是输出。r

随机推荐