spring事物管理

147 阅读3分钟

「这是我参与2022首次更文挑战的第14天,活动详情查看:2022首次更文挑战」。

事务认识

所了解的事务Transaction,它是一些列严密操作动作,要么都操作完成,要么都回滚撤销。Spring事务管理基于底层数据库本身的事务处理机制。数据库事务的基础,是掌握Spring事务管理的基础

事务具备ACID四种特性,ACID是Atomic(原子性)、Consistency(一致性)、Isolation(隔离性)和Durability(持久性)的英文缩写。 

  • 原子性: 事务应该当作一个单独单元的操作,这意味着整个序列操作要么是成功,要么是失败的。
  • 一致性: 这表示数据库的引用完整性的一致性,表中唯一的主键等。
  • 隔离性: 可能同时处理很多有相同的数据集的事务,每个事务应该与其他事务隔离,以防止数据损坏。
  • 持久性: 一个事务一旦完成全部操作后,这个事务的结果必须是永久性的,不能因系统故障而从数据库中删除。

Spring 声明式事务管理

所谓声明式事务,就是通过配置的方式省去很多代码,从而让Spring来帮你管理事务。本质上就是配置一个Around方式的AOP,在执行方法之前,用TransactionInterceptor截取,然后调用PlatformTransactionManager的某个实现做一些事务开始前的事情,然后在方法执行后,调用PlatformTransactionManager的某个实现做commit或rollback。

  • 我们使用标签,它创建一个事务处理的建议,同时,我们定义一个匹配所有方法的切入点,我们希望这些方法是事务型的并且会引用事务型的建议。
  • 如果在事务型配置中包含了一个方法的名称,那么创建的建议在调用方法之前就会在事务中开始进行。
  • 目标方法会在 try / catch 块中执行。
  • 如果方法正常结束,AOP 建议会成功的提交事务,否则它执行回滚操作

使用XML进行配置事务管理器

利用aop的思想,将需要事务管理的业务方法通过xml配置的方式,将事务管理加在该类的相关方法上。这种方法的优点是,一次xml配置,后期不用关心业务类增加或者减少,通过xml中配置的匹配信息,会去找业务类所在的包和方法,然后加上事务。重点是配置tx:adviceaop:config上。

示例:

 <!--  spring transaction aspectj xml -->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <tx:method name="transfer" propagation="REQUIRED"/>
        </tx:attributes>
    </tx:advice>
    <aop:config>
        <aop:pointcut expression="execution(* com.xxx.springtransaction.service..*(..))"
           id="pointcut"/>
        <aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut"/>
    </aop:config>

基于注解的方式: @Transactional

事物传播行为介绍:

  •   @Transactional(propagation=Propagation.REQUIRED) :如果有事务, 那么加入事务, 没有的话新建一个(默认情况下)
  •   @Transactional(propagation=Propagation.NOT_SUPPORTED) :容器不为这个方法开启事务
  •   @Transactional(propagation=Propagation.REQUIRES_NEW) :不管是否存在事务,都创建一个新的事务,原来的挂起,新的执行完毕,继续执行老的事务
  •   @Transactional(propagation=Propagation.MANDATORY) :必须在一个已有的事务中执行,否则抛出异常
  •   @Transactional(propagation=Propagation.NEVER) :必须在一个没有的事务中执行,否则抛出异常(与Propagation.MANDATORY相反)
  •   @Transactional(propagation=Propagation.SUPPORTS) :如果其他bean调用这个方法,在其他bean中声明事务,那就用事务.如果其他bean没有声明事务,那就不用事务. 示例
@Transactional
public class AccountServiceImpl implements AccountService {
    
    private AccountDao accountDao;
    public void setAccountDao(AccountDao accountDao) {
        this.accountDao = accountDao;
    }
    @Override
    public void transfer(String out, String in, Double money) { 
        accountDao.transferOut(out, money);
        //int i = 1/0;
        //System.out.println(i);
        accountDao.transferIn(in, money);
    }
​
 
}

对于spring事务管理而言,如果是springmvc的项目,倾向于使用xml配置的方式,如果是springboot了,只能使用注解的方式。