Spring 事务操作中配置参数和完全注解声明式开发

2022-01-04 0 By admin

一、声明式事务管理参数配置

在service 类上面添加注解@Transactional,在这个注解里面可以配置事务相关参数。

1.1、ioslation:事务隔离级别

  1. 事务有特性成为隔离性,多事务操作之间不会产生影响。不考虑隔离性产生很多问题
  2. 有三个读问题:脏读、不可重复读、虚(幻)读
  3. 解决:通过设置事务隔离级别,解决读问题

1.2、timeout:超时时间

  1. 事务需要在一定时间内进行提交,如果不提交进行回滚
  2. 默认值是-1 ,设置时间以秒单位进行计算

1.3、readOnly:是否只读

  1. 读:查询操作,写:添加修改删除操作
  2. readOnly 默认值false,表示可以查询,可以添加修改删除操作
  3. 设置readOnly 值是true,设置成true 之后,只能查询

1.4、rollbackFor和noRollbackFor

  1. rollbackFor:设置出现哪些异常进行事务回滚
  2. noRollbackFor:设置出现哪些异常不进行事务回滚

二、propagation:事务传播行为

多事务方法间直接进行调用,这个过程中事务是如何进行管理的。
Spring中七种Propagation类的事务属性详解:

  1. REQUIRED:支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。
  2. SUPPORTS:支持当前事务,如果当前没有事务,就以非事务方式执行。
  3. MANDATORY:支持当前事务,如果当前没有事务,就抛出异常。
  4. REQUIRES_NEW:新建事务,如果当前存在事务,把当前事务挂起。
  5. NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
  6. NEVER:以非事务方式执行,如果当前存在事务,则抛出异常。
  7. NESTED:支持当前事务,如果当前事务存在,则执行一个嵌套事务,如果当前没有事务,就新建一个事务。

2.1、PROPAGATION_REQUIRED 默认

说明: 如果当前已经存在事务,那么加入该事务,如果不存在事务,创建一个事务,这是默认的传播属性值。

@Transactional
public void service(){
    serviceA();
    serviceB();
}

@Transactional
serviceA();
@Transactional
serviceB();

serviceA 和 serviceB 都声明了事务,默认情况下,propagation=PROPAGATION_REQUIRED,整个service调用过程中,只存在一个共享的事务,当有任何异常发生的时候,所有操作回滚。

2.2、PROPAGATION_SUPPORTS

说明:如果当前已经存在事务,那么加入该事务,否则创建一个所谓的空事务(可以认为无事务执行)。

public void service(){
     serviceA();
     throw new RunTimeException();
}

@Transactional(propagation=Propagation.SUPPORTS)
serviceA();

serviceA执行时当前没有事务,所以service中抛出的异常不会导致 serviceA回滚。

public void service(){
     serviceA();
}
@Transactional(propagation=Propagation.SUPPORTS)
serviceA(){
    do sql 1
    1/0;
    do sql 2
}

由于serviceA运行时没有事务,这时候,如果底层数据源defaultAutoCommit=true,那么sql1是生效的,如果defaultAutoCommit=false,那么sql1无效,如果service有@Transactional标签,serviceA共用service的事务(不再依赖defaultAutoCommit),此时,serviceA全部被回滚。

三、完全注解声明式事务管理

3.1、创建配置类,使用配置类替代xml 配置文件

@Configuration //配置类
@ComponentScan(basePackages = "com.atguigu") //组件扫描
@EnableTransactionManagement //开启事务
public class TxConfig {
	//创建数据库连接池
	@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;
	}
	//创建JdbcTemplate 对象
	@Bean
	public JdbcTemplate getJdbcTemplate(DataSource dataSource) {
		//到ioc 容器中根据类型找到dataSource
		JdbcTemplate jdbcTemplate = new JdbcTemplate();
		//注入dataSource
		jdbcTemplate.setDataSource(dataSource);
		return jdbcTemplate;
	}
	//创建事务管理器
	@Bean
	public DataSourceTransactionManager
		getDataSourceTransactionManager(DataSource dataSource) {
		DataSourceTransactionManager transactionManager = new
		DataSourceTransactionManager();
		transactionManager.setDataSource(dataSource);
		return transactionManager;
	}
}