3、事务

1、基础

什么是事务

  • A:原子性
  • C:一致性
  • I:隔离性
  • D:持久性

控制事务的底层都是 Connection 对象完成的

// JDBC
Connection.setAutoCommit(false);
Connection.commit()
Connection.rollback();

// Mbatis
sqlSession(Connection).commit();
sqlSession(Connection).rollback();

2、Spring 事务

Spring 通过 AOP 的方式进行事务开发

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-tx</artifactId>
    <version>5.1.14.RELEASE</version>
</dependency>
@Transactional

<!--读取 jdbc 配置文件-->
<context:property-placeholder location="classpath:jdbc.properties"/>

<!--配置德鲁伊连接池-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
    <property name="username" value="${jdbc_username}" />
    <property name="password" value="${jdbc_password}" />
    <property name="url" value="${jdbc_url}" />
    <property name="driverClassName" value="${jdbc_driver}" />
</bean>

<!--配置事务管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource"/>
</bean>

<!--开启事务注解, 默认 JDK, ture 为 Cglib-->
<tx:annotation-driven transaction-manager="transactionManager"/>
<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>

3、事务属性

隔传只超异

  • 隔离属性 isloation
  • 传播属性 propagaton
  • 只读属性 readOnly
  • 超时属性 timeout
  • 异常属性 rollbackFor、noRollbackFor
@Transactional(isloation =, propagation =, readOnly =, timeout =, rollbackFor =, noRollbackFor =)

3.1、隔离属性

读未提交、读已提交、可重复读、序列化
实战:推荐使用 Spring 指定的 ISOLATION_DEFAULT,未来实战中,并发访问情况很低,如果真遇到并发问题,乐观锁(MyBatis 通过拦截器自定义开发)

3.2、传播行为

同一时间只会保证有一个事务的存在

* 增删改  ⽅法:  直接使用默认值 REQUIRED
* 查询的  方法:  显示指定传播属性的值为 SUPPORTS
传播属性的值 外部不存在事务 外部存在事务 用法 备注
REQUIRED 开启新的事务 融合到外部事务中 @Transactional(propagation = Propagation.REQUIRED) 增删改方法(默认)
SUPPORTS 不开启事务 融合到外部事务中 @Transactional(propagation = Propagation.SUPPORTS) 查询方法
REQUIRES_NEW 开启新的事务 挂起外部事务,创建新的事务 @Transactional(propagation = Propagation.REQUIRES_NEW) 记录日志方法
NOT_SUPPORTED 不开启事务 挂起外部事务 @Transactional(propagation = Propagation.NOT_SUPPORTED) 及其不常用
NEVER 不开启事务 抛出异常 @Transactional(propagation = Propagation.NEVER) 及其不常用
MANDATORY 抛出异常 融合到外部事务中 @Transactional(propagation = Propagation.MANDATORY) 及其不常用
NESTED 开启新的事务 嵌套事务内执行 @Transactional(propagation = Propagation.NESTED) 及其不常用

3.3、只读属性

针对于只进行查询操作的业务方法,可以加入只读属性,提供运行效率(默认 false)

3.4、超时属性

指定了事务等待的最长时间

1. 为什么事务进行等待?
   当前事务访问数据时, 有可能访问的数据被别的事务进⾏加锁的处理, 那么此时本事务就必须进行等待
2. 等待时间(秒)
   @Transactional(timeout = 2)
3. 超时属性的默认值 -1
   最终由对应的数据库来指定

3.5、异常属性

Spring 事务处理过程中

* 默认 对于 Error、RuntimeException 及其子类, 采用的是回滚的策略
* 默认 对于 Exception 及其子类, 采用的是提交的策略
* 建议: 实战中使用 RuntimeExceptin 及其子类, 使用事务异常属性的默认值

4、事务属性总结

1. 隔离属性  默认值
2. 传播属性  增删改  Required(默认值), 查询操作 Supports
3. 只读属性  增删改  false, 查询操作 true
4. 超时属性  默认值  -1
5. 异常属性  默认值

* 增删改操作
  @Transactional
* 查询操作
  @Transactional(propagation = Propagation.SUPPORTS, readOnly = true)

5、xml 配置事务

<!--配置事务管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource"/>
</bean>

<!--service 中负责进⾏增删改操作的⽅法都以 modify 开头, 查询操作命名⽆所谓-->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
    <tx:attributes>
        <tx:method name="modify*"></tx:method>
        <tx:method name="*" propagation="SUPPORTS" readonly="true"></tx:method>
    </tx:attributes>
</tx:advice>

<!--应⽤的过程中, service 放置到 service 包中-->
<aop:config>
    <aop:pointcut id="pt" expression="execution(* com.zzw.service..*.*(..))"/>
    <aop:advisor advice-ref="txAdvice" pointcut-ref="pt"/>
</aop:config>
posted @ 2023-07-12 15:51  lidongdongdong~  阅读(9)  评论(0编辑  收藏  举报