Spring中Transactional注解使用的心得

发布时间:2022-10-21 09:59

@Transactional注解是用于事务控制的,需要知道事务的ACID特征:即原子性(Atomicity,或称不可分割性)、一致性(Consistency)、隔离性(Isolation,又称独立性)、持久性(Durability)。

事务是用来控制数据的ACID特性的,用于保证数据的正确性和完整性。

@Transactional注解有两种使用方式:

(1)标注在类上面:当作用于类上时,该类的所有public方法将都具有该类型的事务属性,同时,我们也可以在方法级别使用该标注来覆盖类级别的定义。

(2)标注在方法上面:当作用于方法上时,只有当该方法发生了异常才会进行回滚,其他的方法不受影响。

在项目中使用,@Transactional(rollbackFor=Exception.class),如果类加了这个注解,那么这个类里面的方法抛出异常,就会回滚,数据库里面的数据也会回滚。在@Transactional注解中如果不配置rollbackFor属性,那么事物只会在遇到RuntimeException的时候才会回滚,加上rollbackFor=Exception.class,可以让事物在遇到非运行时异常时也回滚。

今天看黑马redis的课,里面讲到了一个事务注解不生效的问题。

究其原因,就在于Spring中事务注解生效的条件。那么接下来就说一下自己的心得。

  • 查了一下资料,就是说如果想让@Transactional注解生效,那么就只有当被代理类对象调用它的事务方法时,事务注解才会起作用。
  • 那如何才能创建代理对象呢,这个Spring也帮我们做好了。
  • 只要使用注入bean的方式(也就是依赖注入的方式)去创建bean对象,该bean对象调用被@T注解了的方法,那么就会走代理类,从而@T注解就起作用了。

以下说一下例子吧

public class VoucherOrderServiceImpl implements IVoucherOrderService
@Override
public Result seckillVocher(Long voucherId) {
	IVoucherOrderService o = (IVoucherOrderService) AopContext.currentProxy();
return o.secKill(voucherId);
	}


@Override
@Transactional
public Result secKill(Long voucherId) {
	
	}
}
  • 在一个方法中调用另一个@T注释的方法,如果直接this.xxx()去调用,那么@T不会生效,上面说的原因嘛,没有走动态代理类。
  • 那怎么办呢,我们手动的创建一个代理类对象就能解决改问题。
  • 为什么要生成IVoucherOrderService这个类型的动态代理类对象呢?-- 这样想:1.我们要去调用该类的@T方法,肯定要指定成该对象类型。2.换个说法,如果使用注入bean的方式调用该@T方法,不也是生成这个类型的代理类对象吗
GoLang与Java各自生成grpc代码流程介绍 生活杂谈

GoLang与Java各自生成grpc代码流程介绍

1.背景: 由于公司的日志系统使用的是plumelog,最近生产环境老是报 jedis连接池不够,导致丢失日志,而且服务老是重启,怀疑跟日志系统有关,于是自己改造plumelog,使用go grpc...
MySQL同步数据Replication的实现步骤 生活杂谈

MySQL同步数据Replication的实现步骤

MySQL提供了Replication功能,可以实现将一个数据库的数据同步到多台其他数据库。前者通常称之为主库(master),后者则被称从库(slave)。MySQL复制过程采用异步方式,但延时非常...
C#编程中最容易犯的7种编写错误分享 生活杂谈

C#编程中最容易犯的7种编写错误分享

编程时犯错是必然的,这篇文章主要和大家来分享7个C#编程中最容易犯的7种编写错误,文中的示例代码讲解详细,感兴趣的小伙伴可以了解一下! 1、拼接字符串 在C#编程中,字符串类型的处理是比较...