一、Spring中的AOP事务

1.1 事务

1.1.1 事务特性ACID

  1. 原子性(Atomicty)
  2. 一致性(Consistency)
  3. 隔离性(Isolation)
  4. 持久性(Durability)

1.1.2 事务并发问题

  1. 脏读
  2. 不可重复读
  3. 幻读

1.1.3 事务的隔离级别

  • 读未提交:1
  • 读已提交:2
  • 可重复读:4
  • 串行化:8

二、Spring中的事务管理

2.1 事务操作

  1. 打开事务
  2. 提交事务
  3. 回滚事务

2.2 事务操作对象

  • 不同平台操作事务的代码都不一样,因此Spring提供了一个接口。PlatformTransactionManager接口。

2.3 !!PlatformTransactionManager接口

  • Spring中事务管理,最为核心的对象就是TransactionManager对象

2.3.1 DataSourceTransactionManager

2.3.2 HibernateTransactionManager

2.4 Spring管理事务的属性介绍

2.4.1 事务的隔离级别

  • 读未提交:1
  • 读已提交:2
  • 可重复读:4
  • 串行化:8

2.4.2 是否只读

  • true:只读
  • false:可操作

2.4.3 事务的传播行为

  1. PROPAGATION_REQUIRED:支持当前事务,如果不存在,就新建一个(<font color="red">默认</font>)
  2. PROPAGATION_SUPPORTS:支持当前事务,如果不存在,就不使用事务。
  3. PROPAGATION_MANDATORY:支持当前事务,如果不存在,抛出异常。
  4. PROPAGATION_REQUIRES_NEW:如果有事务存在,挂起当前事务,创建一个新的事务
  5. PROPAGATION_NOT_SUPPORTED:以非事务方式运行,㘝有事务存在,挂起当前事务。
  6. PROPAGATION_NEVER:以非事务方式运行,如果有事务存在,抛出异常
  7. PROPAGATION_NESTED:如果当前事务存在,则嵌套事务执行

三、Spring管理事务方式

  • 原理图

3.1 xml配置(aop)

3.1.1 导包

  1. aop
  2. aspect
  3. aop-alliance
  4. aop-weaver

3.1.2 导入新的约束(tx)

  1. beans:最基本
  2. context:读取properties配置
  3. aop:配置aop
  4. tx:配置事务通知

3.1.3 配置通知

<!-- 0.注册dataSource --> <bean name="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="driverClass" value="com.mysql.jdbc.Driver"></property> <property name="jdbcUrl" value="jdbc:mysql:///ssh"></property> <property name="user" value="root"></property> <property name="password" value="123456"></property> </bean> <!-- 1.注册事务管理的核心对象 - 通知类 --> <bean name="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"></property> </bean> <!-- 2.配置事务管理的具体通知属性,需要添加新的命名空间tx 隔离级别、只读性、传播行为 transaction-manager:可以省略,自动找transactionManager对象 --> <tx:advice id="tx" transaction-manager="transactionManager"> <tx:attributes> <tx:method name="transfer" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false"/> <tx:method name="get*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="true"/> <tx:method name="find*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="true"/> <tx:method name="save*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false"/> <tx:method name="presist*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false"/> <tx:method name="update*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false"/> <tx:method name="modify*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false"/> <tx:method name="delete*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false"/> <tx:method name="remove*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false"/> </tx:attributes> </tx:advice> <!-- 3.aop织入 --> <aop:config> <aop:pointcut expression="execution(* d_transaction.*ServiceImpl.*(..))" id="pc"/> <aop:advisor advice-ref="tx" pointcut-ref="pc"/> </aop:config>

3.1.4 配置将通知织入目标

  • 见是上第三步!

3.2 注解配置(aop)

3.2.1 导包(同xml)

3.2.2 导入新的约束tx(同上)

3.2.3 开启注解管理事务

  • 记得开注解包扫描

    • <context:component-scan base-package="d_transaction_annotation"></context:component-scan>
  • 记得开启使用注解管理aop事务

    • `<tx:annotation-driven transaction-manager="transactionManager"/>
      </beans>`
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd"> <!-- 1.开启注解包扫描 @Service @Controller @Repository @Component --> <context:component-scan base-package="d_transaction_annotation"></context:component-scan> <!-- 2.注册dao --> <bean name="accountDao" class="d_transaction_annotation.AccountDaoImpl"> <property name="dataSource" ref="dataSource"></property> </bean> <!-- 1.引入src/db.properties配置文件 --> <context:property-placeholder location="classpath:db.properties"/> <!-- 3.注册dataSource --> <bean name="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="driverClass" value="${jdbc.driverClass}"></property> <property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property> <property name="user" value="root"></property> <property name="password" value="123456"></property> </bean> <!-- 1.注册事务管理的核心对象 - 通知类 --> <bean name="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"></property> </bean> <!-- 使用注解来配置事务的属性以及织入 @Transactional --> <tx:annotation-driven transaction-manager="transactionManager"/> </beans>

3.2.4 使用注解

  • @Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED, readOnly = false)
package d_transaction_annotation; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Isolation; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; @Service // 对类中所有方法生效 @Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED, readOnly = true) public class AccountServiceImpl implements AccountService { @Autowired private AccountDao ad; @Override // 转账业务 // 对当前方法生效 @Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED, readOnly = false) public void transfer(int fromId, int toId, double money) { // 减钱 ad.decrement(fromId, money); // int a = 1/0; // 加钱 ad.increment(toId, money); } }
Last modification:September 8th, 2019 at 10:16 am