Spring5-事务
1.事务操作(概念)
- 什么是事务:
(1)事务是数据库操作最基本单元,是逻辑上的一组操作.只有两种情况:
a.都成功
b.有一个失败则为失败
(2)典型场景: 银行转账
eg. a ->(100$) -> b - 事务的四大特性(ACID)
(1)原子性: 过程不可分割
(2)一致性: 操作前与操作后总量不变
(3)隔离性: 多事务操作时,互相不会产生影响
(4)持久性: 事务提交后表中数据发生变化
2.事务操作(搭建事务操作环境)
示例:转账(lucy转账100给mary)
service:业务操作 创建转账的方法 调用dao两个的方法
dao:数据库操作(不写业务) 创建两个方法:少钱、多钱
-
创建数据库表,添加记录
-
创建service,搭建dao,完成对象创建和注入关系
service注入dao,在dao注入JdvcTemplate,在JdbcTemplate中注入DataSource -
在dao创建两个方法:多钱和少钱的方法;在service创建转账的方法
-
上述方法不会处理异常情况(转账情况断电)
(1)使用事务进行解决
(2)事务操作过程 开启事务->事务操作->无异常?commit:rollback;
3.事务操作(Spring事务管理介绍)
-
事务添加到javaee中的service层(业务逻辑层)
-
Spring进行事务管理操作
两种方式:编程式事务管理,声明式事务管理 -
声明式事务管理
(1)基于注解方式
(2)基于xml配置文件方式 -
Spring进行声明式事务管理,底层使用AOP
-
Spring事务管理API
(1)提供接口:代表事务管理器,这个接口针对不同框架提供不同实现类
声明式事务管理(注解方式)
- 在Spring配置文件中配置事务管理器
Eg
<bean id="transcationManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!--注入数据源-->
<property name="dataSource" ref="dataSource"></property>
</bean>
-
开启事务注解
(1)在Spring配置文件中引入名称空间tx
(2)开启事务注解 -
在service类上面(获取service类里面方法上面)添加事务注解
@Transactional
添加到类上面:这个类里面所有的方法都添加事务
添加到方法上面:为这个方法添加事务
声明式事务管理(完全注解方式)
- 创建配置类,使用配置类替代xml配置文件
eg.
@Configuration
@ComponentScan(basePackages = "Transaction.service")
@EnableTransactionManagement //开启事务
public class TxConfig {
//创建数据库连接池
@Bean
public DruidDataSource getDruidDataSource(){
DruidDataSource dataSource = new DruidDataSource();
dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
dataSource.setUrl("jdbc:mysql:///user_db?serverTimezone=UTC");
dataSource.setUsername("root");
return dataSource;
}
//创建Jdbc对象
@Bean
public JdbcTemplate getJdbcTemplate(DataSource dataSource){ //到ioc容器中根据类型找到dataSource
//注入dataSource
JdbcTemplate jdbcTemplate = new JdbcTemplate();
jdbcTemplate.setDataSource(dataSource);
return jdbcTemplate;
}
//创建事务管理器
@Bean
public DataSourceTransactionManager getDataSourceTranscationManager(DataSource dataSource){
DataSourceTransactionManager transactionManager = new DataSourceTransactionManager();
transactionManager.setDataSource(dataSource);
return transactionManager;
}
}
声明式事务管理(xml)
-
在spring配置文件中进行配置
-
配置通知(增强的那部分)
-
配置切入点和切面(哪个方法;事务加到方法的过程)
eg.
<!--1. 创建事务管理器-->
<bean id="transcationManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!--注入数据源-->
<property name="dataSource" ref="dataSource"></property>
</bean>
<!--2. 配置通知 -->
<tx:advice id="txadvice">
<!--配置事务参数-->
<tx:attributes>
<!--在指定的哪种规则方法上添加事务-->
<tx:method name="accountMoney" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
<!--3. 配置切入点和切面-->
<aop:config>
<!--配置切入点-->
<aop:pointcut id="pt" expression="execution(* Transaction.dao.UserDao.*(..))"/>
<!--配置切面-->
<aop:advisor advice-ref="txadvice" pointcut-ref="pt"></aop:advisor>
</aop:config>
声明式事务管理参数配置
-
在service类上面添加注解@Transactional,在这个注解里面可以配置事务相关参数
-
propagation:事务的传播行为
@Transactional(propagation = Propagation.REQUIRED)
(1)多事务方法之间进行调用,这个过程中事务是如何进行管理的(有无事务管理方法之间)
(2)七种事务传播行为(add方法有事务,update方法无事务)
-
REQUIRED: 若add方法本身无事务,调用update方法后创建新事务;若add方法本身有事务,调用update方法后创建新事物
-
REQUIRED_NEW: 使用add方法调用update方法,add无论是否有事务都将创建新事务
- isolation:事务的隔离级别
@Transactional(propagation = Propagation.REQUIRED,isolation = Isolation.READ_COMMITTED)
(1)事务有特性成为隔离性,多事务操作之间不会产生影响,不考虑隔离性产生很多问题
(2)有三个读问题:脏读,不可重复读,幻读
- 脏读:read uncommited 一个未提交事务读取到另一个未提交事务的数据
- 不可重复读:read commited 一个未提交事务读取到另一个提交事务的修改数据
- 幻读:repeatable read 一个未提交事务读取到另一个提交事务添加数据
- serializable(串行化) 全部解决
(3)设置事务隔离性解决问题
-
timeout:超时时间
@Transactional(timeout = -1,propagation = Propagation.REQUIRED,isolation = Isolation.READ_COMMITTED)
(1)事务需要在一定时间内提交,否则回滚
(2)默认值:-1(不超时),设置时以秒为单位 -
readOnly:只读
@Transactional(readOnly = false,timeout = -1,propagation = Propagation.REQUIRED,isolation = Isolation.READ_COMMITTED)
(1)readOnly默认值false,标识可以查询,可以添加修改删除操作
(2)设为true则只能查询 -
rollbackFor: 回滚
(1)设置出现哪些异常进行事务回滚 -
noRollbackFor: 不回滚
(1)设置出现哪些异常不进行事务回滚