【Spring】事务

120 阅读2分钟

事务作用:在数据层保障一系列的数据库操作一致性(同时成功,同时失败

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

案例1:模拟银行账号间转账

A账户减钱,B账户加钱

那么什么是“同时成功、同时失败”呢?

“A账户减钱操作”后,出现了异常,导致“B账号加钱操作”不能正常执行。那么此时A操作成功B操作失败就不是“同时成功同时失败”。

即:异常之前操作成功,异常之后操作失败,整体业务失败。

1 配置当前接口方法具有事务

@Transactional

Transactional [træn'zækʃənəl] adj. 相互作用的;事务性的,事务处理的

//AccountService.java
@Transactional
public void transfer(String out,String in ,Double money);

//直接写在接口上
@Transactional
public interface AccountService {
    /**
     * 转账操作
     * @param out 传出方
     * @param in 转入方
     * @param money 金额
     */
    public void transfer(String out,String in ,Double money) ;
}

2 配置事务管理器

//JdbcConfig.java
@Bean
public PlatformTransactionManager transactionManager(DataSource dataSource){
    DataSourceTransactionManager transactionManager = new DataSourceTransactionManager();
    transactionManager.setDataSource(dataSource);
    return transactionManager;
}

事务管理器要根据技术进行选择。例,MyBatis框架使用的是JDBC事务

PlatformTransactionManager:Spring提供的标准接口

DataSourceTransactionManager:JDBC事务(可换)

注入参数DataSource dataSource

3 开启注解式事务驱动

@EnableTransactionManagement

...
@EnableTransactionManagement
public class SpringConfig {
}

Code

//AccountServiceImpl.java
@Transactional
public void transfer(String out,String in ,Double money) {
    accountDao.outMoney(out,money);
    accountDao.inMoney(in,money);
}
//AccountDao.java
@Update("update tbl_account set money = money + #{money} where name = #{name}")
void inMoney(@Param("name") String name, @Param("money") Double money);

@Update("update tbl_account set money = money - #{money} where name = #{name}")
void outMoney(@Param("name") String name, @Param("money") Double money);

事务角色

在没有开启Spring事务前,outMoney和inMoney都会“开启事务”,但是开启的事务不同:开启事务T1、开启事务T2

开启Spring事务后(开启事务T)【事务管理员】,两个操作加入事务T中【事务协调员】

事务管理员

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

事务协调员

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

事务相关配置

1readOnly = true1:只读事务

1timeout = -11:永不超时

@Transactional(readOnly = true, timeout = -1)

1rollbackFor1:设置事务的回滚异常

有些异常(IOExceprtion)不会触发回滚,得手动加上

@Transactional(rollbackFor = IOException.class)

案例2:log

事务传播行为:事务协调员事务管理员 所携带事务的处理态度。

//propagation设置事务属性:传播行为设置为当前操作需要新事务
@Transactional(propagation = Propagation.REQUIRES_NEW)