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>
本文来自博客园,作者:lidongdongdong~,转载请注明原文链接:https://www.cnblogs.com/lidong422339/p/17547716.html