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

Spring的事务控制

一、声明式事务

(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同时存在。

相关文章:

  • 电商网站开发教学视频/网站模板商城
  • 中山网站建设文化咨询/电子商务软文写作
  • 网站服务器地址在哪里看/品牌营销策略分析
  • 营口做网站/文明seo技术教程网
  • 给一个免费的网站/百度北京总部电话
  • 黑龙江省建设工程质量安全协会网站/百度主页
  • JavaScript:代码风格
  • JAVA【数据库DB 一】
  • 大数据必学Java基础(七十七):线程的生命周期和常见方法
  • web前端网页设计作业—个人网页(游戏主题)(html+css+js)
  • 2022-2023 ICPC Brazil Subregional Programming Contest VP记录
  • EMC诊断技术及电磁兼容理论设计
  • 升压IC可提升白光LED的电池电压
  • npm install ,npm ERR code 401 Incorrect or missing password 错误原因与.npmrc 配置文件的使用
  • 二十七、Hive分析搜索引擎用户行为数据
  • Kubernetes_14_静态Pod网关apiserver底层都是restful接口
  • buuctf刷题8 (ssti注入nmap- oG指令别样的sql注入)
  • python中的迭代器,可迭代对象(详细剖析)