一、事务概念
概念:逻辑上的一组操作要么都成功,要么都失败,如银行转账,转账的钱扣了,由于各种原因,导致收钱方没到,钱就没了
事务的四个特性(ACID):
1、原子性:要么都成功,要么都失败
2、一致性:总量相同 A200 B200 总共400,不会凭空多钱
3、隔离性:两边同时操作同一条数据,不会产生影响
4、持久性:提交后表里面的数据会变化
二、环境搭建
1.创建数据库
二导入相关jar包
<dependencies>
<!--AOP相关的依赖-->
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>2.2.2</version>
</dependency>
<dependency>
<groupId>aopalliance</groupId>
<artifactId>aopalliance</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.13</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
<!--IOC相关的依赖-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>5.2.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.2.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
<version>5.2.6.RELEASE</version>
</dependency>
<!-- 数据库相关依赖-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.16</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.10</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.1.9.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
<!--与事务相关的-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>5.0.3.RELEASE</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13</version>
</dependency>
</dependencies>
三创建Mapper提供加钱减钱的方法
@Repository
public class MapperImpl implements Mapper {
@Resource
private JdbcTemplate jdbcTemplate;
@Override
public void addMoney(int money) {
String sql = "update account set money = money+?";
jdbcTemplate.update(sql,money);
}
@Override
public void subtract(int money) {
String sql = "update account set money = money-?";
jdbcTemplate.update(sql,money);
}
}
四、模拟转账场景
@Service
public class MyService {
@Resource
private Mapper mapper;
// 模拟转账的场景
public void translate(){
// id = 1转给id =2 100;
// 1号-100
mapper.subtract(100,1);
//2号+100
mapper.addMoney(100,2);
}
}
这样转账过程正常,但复杂业务通常没那么简单,转账和到账之间还有一系列的程序在跑,可能出现异常,导致只执行的扣钱,但没执行到加钱,如下面,这就导致了问题
这就需要开启事务管理了
三 、事务操作
1.事务添加到业务层(Service)
2.在spring事务管理有两种方式:
- 编程式事务管理:在代码中写
- 声明式事务管理:底层AOP原理的(我们要学的)
3.声明式事务管理可以用注解和配置文件实现
4、相关的API(类)
根据不同的框架提供不同的类,我们这边使用的是DataSourceTransactionManager
5.基于注解实现声明式事务管理
第一步:配置事务管理器,需要注入DataSource
<!-- 创建事务管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
第二步:开启事务注解
<tx:annotation-driven transaction-manager="transactionManager"/>
第三步:在需要开启事务的方法或类加上@Transactional的注解
通过配置事务管理的相关参数,可以实现不同的效果
6、xml声明式事务管理
第一步:配置事务管理器,与前面相同
第二步:配置通知
<!--配置通知-->
<tx:advice id="txadvice">
<!-- 配置事务参数-->
<tx:attributes>
<!--什么方法添加事务,也可以配置其他事务相关的参数-->
<tx:method name="translate" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
第三步:配置切入点和切面
<!--配置切入点(增强的是具体哪个方法)和切面(动作)-->
<aop:config>
<aop:pointcut id="pt" expression="execution(* com.ls.service.MyService.translate(..))"/>
<aop:advisor advice-ref="txadvice" pointcut-ref="pt"/>
</aop:config>
7、完全注解开发
创建配置类,spring boot的雏形