Spring事务简介
- 事务作用:在数据层保障一系列的数据库操作同成功同失败
- Spring事务作用:在数据层或业务层保证一系列的数据库操作同成功同失败
public interface PlatformTransactionManager{
void commit(TransactionStatus status) throws TransactionException;
void rollback(TransactionStatus status) throws TransactionException;
}
public class DataSourceTransactionManager{
......
}
案例:银行转账操作
A向B转账100,数据库中A的金额数减少,B的金额数增加
①:在业务层接口上添加Spring事务管理
public interface AccountService{
@Transactional
public void transfer(String out,String in,Double money);
}
注意:Spring注解式事务通常添加在业务层接口中而不会添加到业务层实现类中,降低耦合
注解式事务可以天交到业务方法上表示当前方法开启事务,也可以添加到接口上表示当前接口所有方法开启事务
②:设置事务管理器
@Bean
public PlatfromTransactionManager transactionManager(DataSource dataSource){
DataSourceTransacionManager ptm = new DataSourceTransactionManager();
ptm.setDataSource(dataSource);
return ptm;
}
③:开启注解式事务驱动
@Configuration
@ComponentScan("com.mei")
@ProperySource("classpath:jdbc.properties")
@Import({JdbcConfig.class,MybatisConfig.calss})
@EnableTransactionManagement
public class SpringConfig{
}
Spring事务角色
如果没用@Transactional开启Spring事务,那么outMoney和inMoney就是两个单独的事务,各干各的不影响,开启事务T之后,T1和T2会加入到事务T,整个流程只有一个事务了,所以一旦有异常就可以进行回滚,做到同成功同失败的操作,开启事务的角色称为事务管理员,加入的为事务协调员
- 事务管理员:发起事务方,在Spring中通常指业务层开启事务的方法
- 事务协调员:计入事务方,在Spring中通常指数据层或者业务层方法
@Transactional //开启事务T
public void transfer(String out,String in,Double money){
accountDao.outMoney(out,money);
accountDao.outMoney(out,money);
}
public interface AccountDao{
@Update("update tbl_account set money = money - #{money} where name = #{name}")
//事务T1
void outMoney (@Param("name") String name,@Param("money") Double money);
//事务T2
void inMoney(@Pram("name") String name,@Param("money") Double money)
}
Spring事务属性
属性 | 作用 | 实例 |
---|---|---|
readOnly | 设置是否为只读 | readOnly = true 只读事务 |
timeout | 设置事务超过时间 | timeout = -1 永不超时 |
roolbackFor | 设置事务回滚异常(class) | rollbackFor={NullPointException.class} |
roobackForClassName | 设置事务回滚异常(String) | 同上,格式为字符串 |
noRollbackFor | 设置事务不回滚异常(class) | noRollbackFor={Null.PointException.class} |
noRollbackForClassName | 设置事务不回滚异常(String) | 同上格式为字符串 |
propagation | 设置事务传播行为 | … |
案例:转账业务追加日志
任意两个账户转账,每次转账操作无论成功必须在数据库留痕+
①:在业务层接口上添加Spring事务,设置事务传播行为REQUIRES_NEW(需要新事物)
@Service
public class LogServiceImpl implements LogService{
@Autowired
private LogDao logDao;
@Transactional(propagetion = Propagetion.REQUIRES_NEW)
public void log(String out,String in,Double money) {
logDao.log("转账操作由"+out"到"+in,"金额:"+money)
}
}
事务传播行为