事务的大千世界(声明式事务、编辑式事务、分布式事务)

前言

  如果您觉得有用的话,记得给博主点个赞,评论,收藏一键三连啊,写作不易啊^ _ ^。
  而且听说点赞的人每天的运气都不会太差,实在白嫖的话,那欢迎常来啊!!!


事务的大千世界(声明式事务、编辑式事务、分布式事务)

1、声明式事务

概述::
Spring 支持声明式事务,使用@Transactional注解在方法上表明该方法需要事务支持,spring Boot自动开启对声明式事务的支持,从原理上这是基于注解式AOP的实现,被注解的方法在被调用时,spring开启一个新的事务,当方法无异常运行结束后,提交事务,@Transactional注解也可以注解在类上,表示该类所有的public方法都开始事务支持。

1.1、@Transactional作用域

@Transactional 可以作用在接口、类、类方法
1)、作用于类:

当把@Transactional 注解放在类上时,表示所有该类的public方法都配置相同的事务属性信息。

2)、作用于方法:

当类配置了@Transactional,方法也配置了@Transactional,方法的事务会覆盖类的事务配置信息。

3)、作用于接口:

不推荐这种使用方法,因为一旦标注在Interface上并且配置了Spring AOP 使用CGLib动态代理,将会导致@Transactional注解失效


1.2、@Transactional用法

属性列表:

序号 属性 含义
1 propagation属性 代表事务的传播行为
2 isolation 属性 事务的隔离级别
3 timeout 属性 事务的超时时间
4 readOnly 属性 指定事务是否为只读事务
5 rollbackFor 属性 用于指定能够触发事务回滚的异常类型,可以指定多个异常类型。
6 noRollbackFor属性 该属性用于设置不需要进行回滚的异常类,抛出指定的异常类型,不回滚事务,也可以指定多个异常类型

详情:

1.2.1、propagation属性

propagation 代表事务的传播行为,默认值为 Propagation.REQUIRED,其他的属性信息如下:

Propagation.REQUIRED:
如果当前存在事务,则加入该事务,如果当前不存在事务,则创建一个新的事务。
Propagation.SUPPORTS:
支持当前事务,若无事务则不用事务
Propagation.MANDATORY:
强制方法在事务中执行,若无事务则抛出异常。
Propagation.REQUIRES_NEW:
无论是否存在事务,都创建一个新的事务,原来的挂起,新的执行完毕,继续执行老的事务
Propagation.NOT_SUPPORTED:
以非事务的方式运行,如果当前存在事务,暂停当前的事务。
Propagation.NEVER:
以非事务的方式运行,如果当前存在事务,则抛出异常。
Propagation.NESTED :
如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与PROPAGATION_REQUIRED类似的操作

1.2.2、isolation 属性

isolation :事务的隔离级别,默认值为Isolation.DEFAULT
该属性用于设置底层数据库的事务隔离级别,事务隔离级别用于处理多事务并发情况,通常使用数据库的默认隔离级别即可

solation.DEFAULT:
使用底层数据库默认的隔离级别。
Isolation.READ_UNCOMMITTED:
A事务修改一条记录但没有提交事务,在B事务可以读取到修改后的记录,不能防止脏读、不可重复读和幻读。
Isolation.READ_COMMITTED:
只有A事务修改一条记录并提交事务,B事务才可以读取到A事务修改后的数据,防止脏读、不可重复读和幻读。
Isolation.REPEATABLE_READ:
不仅仅能实现【Isolation.READ_COMMITTED】的功能,并且当A事务读取一条记录,B事务将不允许修改这条记录,防止脏读和不可重复读,但不防止幻读。
Isolation.SERIALIZABLE:
最可靠的事务隔离级别,此级别下的事务是顺序执行的,可防止脏读、不可重复读和幻读,但开销大。

1.2.3、timeout 属性

timeout :事务的超时时间,默认值为 -1。如果超过该时间限制但事务还没有完成,则自动回滚事务。【int整形】

1.2.4、readOnly 属性

readOnly :指定事务是否为只读事务,默认值为 false;为了忽略那些不需要事务的方法,比如读取数据,可以设置 read-only 为 true。

1.2.5、rollbackFor 属性

rollbackFor :用于指定能够触发事务回滚的异常类型,可以指定多个异常类型。

1.2.6、noRollbackFor属性

noRollbackFor:
该属性用于设置不需要进行回滚的异常类,抛出指定的异常类型,不回滚事务,也可以指定多个异常类型


1.3、@Transactional失效场景

列表:

序号 失效场景
1 @Transactional 应用在非 public 修饰的方法上
2 @Transactional 注解属性 propagation 设置错误
3 @Transactional 注解属性 rollbackFor 设置错误
4 同一个类中方法调用,导致@Transactional失效
5 异常被你的 catch“吃了”导致@Transactional失效
6 数据库引擎不支持事务
7 @Transactional注解用在接口上,并且配置Spring AOP 使用CGLib动态代理

2、自定义编辑式事务

简单来说利用切面拦截的方式来制作自定义事务:
即:

  1. 执行方法前开启事务
  2. 执行方法
  3. 执行方法后提交事务或回滚事务

举例:

2.1、编辑式事务切面注解:

/**
* 编辑自定义事务控制注解
* @author yangzhenyu
* */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Documented
public @interface TransactionalSelf {
    
    
}

2.2、编辑式事务切面注解实现:

/**
* 编辑自定义事务控制注解
* @author yangzhenyu
* */
@Aspect
@Component
@EnableAspectJAutoProxy(exposeProxy = true,proxyTargetClass = true)
public class TransactionalSelfAspect {
    
    


    private static Logger log = LoggerFactory.getLogger(TransactionalSelfAspect.class);
    @Pointcut("@annotation(com.yzy.demo.transactional.annotation.TransactionalSelf)")
    public void pointcut(){
    
    };
    //事务处理类
    @Autowired
    private DataSourceTransactionManager manager;


    /**事务切面处理方法
     * */
    @Around("pointcut()")
    public Object cut(ProceedingJoinPoint point) throws Throwable{
    
    
        DefaultTransactionDefinition def = new DefaultTransactionDefinition();
        //如果当前没有事务,就新建一个事务,如果已经存在事务,就加入当前事务
        def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED); //事务传播行为
        def.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED);
        TransactionStatus status = manager.getTransaction(def);
        Object result = null;
        try{
    
    
            result = point.proceed();
            //提交事务
            manager.commit(status);
        }catch (Exception e){
    
    
            //回滚事务
            manager.rollback(status);
            log.error("==========================回滚事务=================================");
        }
        return result;
    }
}

3、分布式事务

3.1、什么是分布式事务,分布式事务应用场景:

前提:
1)、微服务架构
2)、库房应用服务和订单应用服务是两个独立的应用服务,并且有独立的数据存储。
业务场景:
当生成新的交易订单时,表示交易完成,交易完成后需扣除相应的库存,
什么是分布式事务:
此场景下,业务逻辑具有原子性,要么同时成功,要么同时失败,为了保证数据一致性,在这里就有分布式事务观念的产生了。
在这里插入图片描述

3.2、分布式事务的特性

1)一般事务的ACID特性

  • 原子性
  • 一致性
  • 隔离性
  • 持久性

2)分布式事务一般都拥有BASE特性

  • 基本可用
  • 柔性状态
  • 最终一致性

总结:出于性能考虑,分布式架构下,分布式事务难以采用强一致性事务方案,只能最求柔性状态、最终一致性,因此分布式事务框架也称柔性事务框架

Guess you like

Origin blog.csdn.net/weixin_38316697/article/details/112536322