spring事务
事务是数据库操作最基本单元,逻辑上一组操作,要么都成功,如果有一个失败则所有操作都失败。(比如:银行转账)
四个特性 (ACID)
- 原子性
- 一致性
- 隔离性
- 持久性
事务操作(环境搭建)
controller + service + dao
事务引入
-
理论上,事务可以加到 JavaEE 三层中的任何层,但最好加到 service 层。
-
在spring 进行事务管理操作
有两种方式,编程式事务管理和声明式事务管理(使用)
-
声明式事务管理
- 基于注解方式
- 基于 xml 配置文件方式
-
在 spring 进行声明式事务管理,底层使用aop
-
spring 事务管理 api
提供了一个接口,代表事务管理器,这个接口针对不同框架提供了不同的实现类。
PlatformTransactionManager
注解声明式事务管理
-
在 spring 配置文件中配置事务管理器
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="datasource"></property> </bean>
-
在 spring 配置文件中开启注解
引入tx命名空间 <!-- 开启事务管理器 --> <tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven>
-
在 service 类上(或者 service 类里面的方法上)添加事务注解
@Service @Transactional public class service{}
(1) @Transactional:既可以添加到类上,也可以添加到方法上
(2) 如果把注解添加到类上,则这个类中的所有方法都将被添加事务
(3) 如果把注解添加到类的方法上,则只为该方法添加事务。
声明式事务管理(参数配置)
-
在 service 类上添加注解 @Transactional ,在这个注解里可以配置事务相关参数。
-
propagation
事务传播行为多事务方法之间进行调用,这个过程中事务是如何进行管理的。
spring框架中 7 中事务传播行为
Required
:如果方法1本身有事务,调用无事务方法2后,统一使用方法1的事务。如果没有事务,将创建一个新的事务,然后在自己的事务内运行。Required_new
:无论方法是否有事务,都创建一个新的事务。Supports
:如果事务在运行,当前方法在该事务内运行,否则它可以不运行在事务中。Not_Supportes
:当前方法不应该运行在事务中,如果有运行的事务,则将他挂起。Mandatory
:当前的方法必须运行在事务内部,如果没有正在运行的事务,就抛出异常。Never
:当前的方法不应该运行在事务中,如果有运行的事务,则直接抛出异常。Nested
:如果有事务在运行,当前的方法就应该在这个事务的嵌套事务内运行,否则就启动一个新的事务,并在他自己的事务内运行。
@Transactional(propagation= Propagation.REQUIRED)
-
isolation
事务隔离级别事务的特性:隔离性,指多事务操作之间不会产生影响,不考虑隔离性会产生很多问题。(脏读,不可重复读,虚读)
-
脏读:多事务。一个未提交事务读取到另一个未提交事务的数据。
事务a 修改了数据,但未提交时,事务b 可以获取到修改后的数据,此时事务a 进行了回滚操作,那么事务b 获取到的数据就是脏数据,进行的行为就是脏读。
-
不可重复读:一个未提交事务读取到另一个已经提交事务的数据。
事务a 和 事务b 都读取到了某条数据,事务b 进行了处理并提价了该操作,使数据发生变化,此时事务a 可以读取到发生变化后的数据。
-
虚读:一个未提交数据读取到另一个提交事务添加的数据。
通过设置事务隔离级别可以解决这三个问题。
级别 脏读 不可重复读 虚读 Read_Uncommitted
(读未提交)有 有 有 Read_Committed
(读已提交)无 有 有 Repeatable_Read
(可重复读)无 无 有 Serializable
(串行化)无 无 无 @Transactional(isolation = Isolation.REPEATABLE_READ) // MYSQL 默认
-
-
timeout
超时事务需要在一定时间内进行提交,超出时间就会进行回滚。
默认为-1,不回滚。设置数字以 秒 为单位。
-
readonly
是否只读读:查询操作,写:添加修改删除操作。
readonly 默认值为 false,表示可写可读。
设置为 true,就只能进行查询操作。
-
rollbackFor
回滚设置出现哪些异常进行事务回滚。
-
noRoolbackFor
不回滚设置出现哪些异常不进行事务回滚。
-
xml 声明式事务管理
在 spring 配置文件中进行配置
- 配置事务管理器
- 配置通知
- 配置切入点和切面
完全注解式 事务操作
-
创建配置类,使用注解,替代xml配置文件
@Configuration @ComponentScan(basePackages="") //组件扫描 @EnableTransactionManagement //开启事务 public class Config{ //创建数据库连接池 @Bean public DruidDataSource getDruidDataSource(){ DruidDataSource dataSource = new DruidDataSource(); dataSource.setDriverClassName("com.mysql.jdbc.Driver"); dataSource.setUrl("jdbc:mysql:///user_db"); dataSource.setUsername("root"); dataSource.setPassword("root"); return dataSource; } //创建事务管理器 @Bean public DataSourceTransactionManager getDataSourceTransactionManager(DataSource dataSource){ DataSourceTransactionManager transactionManager = new DataSourceTransactionManager(); transactionManager.setDataSource(dataSource); return transactionManager; } }