Spring事务


Spring事务

一、Spring事务简介

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

(1)接口

(2)实现类

二、案例:银行账户转账

2.1 业务分析

2.2 实例

2.2.1 在业务层接口上添加Spring事务管理

public interface AccountService {
    /**
     * 转账操作
     * @param out 传出方
     * @param in 转入方
     * @param money 金额
     */
    //配置当前接口方法具有事务
    @Transactional
    public void transfer(String out,String in ,Double money) ;
}
  • 注意事项:Spring注解式事务通常添加在业务层接口中而不会添加到业务层实现类中,降低耦合。
  • 注解式事务可以添加到业务方法上表示当前方法开启事务,也可以添加到接口上表示当前接口所有方法开启事务。

2.2.2 设置事务管理器

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事务。

2.2.3 开启注解式事务驱动

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

2.3 总结

  • 在转换的业务出现错误后,事务就可以控制回顾,保证数据的正确性。

三、Spring事务角色

3.1 事务管理员

  • 发起事务方,在Spring中通常指代业务层开启事务的方法。

3.2 事务协调员

  • 加入事务方,在Spring中通常指代数据层方法,也可以是业务层方法。

四、Spring事务属性

4.1 事务配置

4.1.1 使用rollbackFor属性来设置出现IOException异常不回滚

@Service
public class AccountServiceImpl implements AccountService {
    @Autowired
    private AccountDao accountDao;
    @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);
    }
}

4.2 案例:转账业务追加日志

4.2.1 案例分析

4.2.2 创建日志表

    create table tbl_log(
        id int primary key auto_increment,
        info varchar(255),
    createDate datetime
)

4.2.3 添加LogDao接口

public interface LogDao {
    @Insert("insert into tbl_log (info,createDate) values(#{info},now())")
    void log(String info);
}

4.2.4 添加LogService接口与实现类

public interface LogService {
    void log(String out, String in, Double money);
}
@Service
public class LogServiceImpl implements LogService {
    @Autowired
    private LogDao logDao;
    @Transactional
    public void log(String out,String in,Double money ) {
        logDao.log("转账操作由"+out+"到"+in+",金额:"+money);
    }
}

4.2.5 在转账的业务中添加记录日志

public interface AccountService {
    /**
     * 转账操作
     * @param out 传出方
     * @param in 转入方
     * @param money 金额
     */
//配置当前接口方法具有事务
    public void transfer(String out,String in ,Double money)throws
            IOException ;
}
@Service
public class AccountServiceImpl implements AccountService {
    @Autowired
    private AccountDao accountDao;
    @Autowired
    private LogService logService;
    @Transactional
    public void transfer(String out,String in ,Double money) {
        try{
            accountDao.outMoney(out,money);
            accountDao.inMoney(in,money);
        }finally {
            logService.log(out,in,money);
        }
    }
}

4.3 事务传播行为

  • 事务传播行为:事务协调员对事务管理员所携带事务的处理态度。
  • 如果要实现“不管转账是否成功,都会记录日志”。可以修改logService改变事务的传播行为。

4.3.1 修改logService改变事务的传播行为

@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);
    }
}

4.3.2 事务传播行为的可选值

  • 对于我们开发实际中使用的话,因为默认值需要事务是常态的。
  • 根据开发过程选择其他的就可以了, 例如案例中需要新事务就需要手工配置。
  • 其实入账和出账操作上也有事务,采用的就是默认值。

声明:三二一的一的二|版权所有,违者必究|如未注明,均为原创|本网站采用BY-NC-SA协议进行授权

转载:转载请注明原文链接 - Spring事务


三二一的一的二