Spring事务

事务作用:

  • 事务作用:在数据层保障一系列的数据库操作同成功同失败
  • Spring事务作用:在数据层或 业务层 保障一系列的数据库操作同成功同失败

Spring为了管理事务,提供了一个平台事务管理器PlatformTransactionManager

Spring事务_第1张图片
commit是用来提交事务,rollback是用来回滚事务。

当然PlatformTransactionManager只是一个接口,Spring还为其提供了一个具体的实现:
Spring事务具体实现
从名称上可以看出,我们只需要给它一个DataSource对象,它就可以帮你去在业务层管理事务。其内部采用的是JDBC的事务。所以说如果你持久层采用的是JDBC相关的技术,就可以采用这个事务管理器来管理你的事务。而Mybatis内部采用的就是JDBC的事务,Spring整合Mybatis就采用DataSourceTransactionManager事务管理器。

Spring事务操作步骤

步骤1:在需要被事务管理的方法上添加注解

public interface AccountService {
    /**
     * 转账操作
     * @param out 传出方
     * @param in 转入方
     * @param money 金额
     */
    //配置当前接口方法具有事务
    public void transfer(String out,String in ,Double money) ;
}

@Service
public class AccountServiceImpl implements AccountService {

    @Autowired
    private AccountDao accountDao;
	@Transactional
    public void transfer(String out,String in ,Double money) {
        accountDao.outMoney(out,money);
        int i = 1/0;
        accountDao.inMoney(in,money);
    }

}

注意:

@Transactional可以写在接口类上、接口方法上、实现类上和实现类方法上

  • 写在接口类上,该接口的所有实现类的所有方法都会有事务
  • 写在接口方法上,该接口的所有实现类的该方法都会有事务
  • 写在实现类上,该类中的所有方法都会有事务
  • 写在实现类方法上,该方法上有事务

Spring事务_第2张图片

步骤2:在JdbcConfig类中配置事务管理器

public class JdbcConfig {
    @Value("${jdbc.driver}")
    private String driver;
    @Value("${jdbc.url}")
    private String url;
    @Value("${jdbc.username}")
    private String userName;
    @Value("${jdbc.password}")
    private String password;

    @Bean
    public DataSource dataSource(){
        DruidDataSource ds = new DruidDataSource();
        ds.setDriverClassName(driver);
        ds.setUrl(url);
        ds.setUsername(userName);
        ds.setPassword(password);
        return ds;
    }

    //配置事务管理器,mybatis使用的是jdbc事务
    @Bean
    public PlatformTransactionManager transactionManager(DataSource dataSource){
        DataSourceTransactionManager transactionManager = new DataSourceTransactionManager();
        transactionManager.setDataSource(dataSource);
        return transactionManager;
    }
}

注意: 事务管理器要根据使用技术进行选择,Mybatis框架使用的是JDBC事务,可以直接使用DataSourceTransactionManager

步骤3:开启事务注解

在SpringConfig的配置类中开启

@Configuration
@ComponentScan("com.itheima")
@PropertySource("classpath:jdbc.properties")
@Import({JdbcConfig.class,MybatisConfig.class
//开启注解式事务驱动
@EnableTransactionManagement
public class SpringConfig {
}

稍微总结一下吧

注解:

@EnableTransactionManagement

名称 @EnableTransactionManagement
类型 配置类注解
位置 配置类定义上方
作用 设置当前Spring环境中开启注解式事务支持

@Transactional

名称 @Transactional
类型 接口注解 类注解 方法注解
位置 业务层接口上方 业务层实现类上方 业务方法上方
作用 为当前业务层方法添加事务(如果设置在类或接口上方则类或接口中所有方法均添加事务)

Spring事务角色

我们举个银行管钱的例子,先来看看没有添加事务的情况:
Spring事务_第3张图片

  • AccountDao的outMoney因为是修改操作,会开启一个事务T1
  • AccountDao的inMoney因为是修改操作,会开启一个事务T2
  • AccountService的transfer没有事务,
  • 运行过程中如果没有抛出异常,则T1和T2都正常提交,数据正确
  • 如果在两个方法中间抛出异常,T1因为执行成功提交事务,T2因为抛异常不会被执行, 就会导致数据出现错误

再来看看添加@Transactional注解后加入Spring事务管理的情况:
Spring事务_第4张图片

  • transfer上添加了@Transactional注解,在该方法上就会有一个事务T
  • AccountDao的outMoney方法的事务T1加入到transfer的事务T中
  • AccountDao的inMoney方法的事务T2加入到transfer的事务T中
  • 这样就保证他们在同一个事务中,当业务层中出现异常,整个事务就会回滚,保证数据的准确性。
  • 事务管理员:发起事务方,在Spring中通常指代业务层开启事务的方法
  • 事务协调员:加入事务方,在Spring中通常指代数据层方法,也可以是业务层方法

注意: 目前的事务管理是基于DataSourceTransactionManagerSqlSessionFactoryBean使用的是同一个数据源。

Spring事务属性

Spring事务_第5张图片

事务配置

上面这些属性都可以在@Transactional注解的参数上进行设置。
个:

@Transactional(rollbackFor = {IOException.class})
          public void transfer(String out,String in ,Double money) throws IOException{
              accountDao.outMoney(out,money);
              //int i = 1/0; //这个异常事务会回滚
              if(true){
                  throw new IOException(); //这个异常事务就不会回滚
              }
              accountDao.inMoney(in,money);
          }
  • readOnly:true只读事务,false读写事务,增删改要设为false,查询设为true。
  • timeout:设置超时时间单位秒,在多长时间之内事务没有提交成功就自动回滚,-1表示不设置超时时间。
  • rollbackFor:当出现指定异常进行事务回滚
  • noRollbackFor:当出现指定异常不进行事务回滚
    并不是所有的异常都会回滚事务
    Spring的事务只会对Error异常和RuntimeException异常及其子类进行事务回滚 ,其他的异常类型是不会回滚的,比如IOException就不回滚此时就可以使用rollbackFor属性来设置出现IOException异常时回滚
  • rollbackForClassName等同于rollbackFor,只不过属性为异常的类全名字符串
  • noRollbackForClassName等同于noRollbackFor,只不过属性为异常的类全名字符串

isolation设置事务的隔离级别

  • DEFAULT :默认隔离级别, 会采用数据库的隔离级别
  • READ_UNCOMMITTED : 读未提交
  • READ_COMMITTED : 读已提交
  • REPEATABLE_READ : 重复读取
  • SERIALIZABLE: 串行化

永远记住哦,事务加在一个里面管理后,一定是同成功同失败的

事务传播行为的可选值

Spring事务_第6张图片

个:

@Service
public class LogServiceImpl implements LogService {

    @Autowired
    private LogDao logDao;
	//propagation设置事务属性:传播行为设置为当前操作需要新事务
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void log(String out,String in,Double money ) {
        logDao.log("转账操作由"+out+"到"+in+",金额:"+money);
    }
}

你可能感兴趣的:(Spring初阶,spring,java,Spring事务管理)