spring的@Transactional注解用法解读

下面是关于“spring的@Transactional注解用法解读”的完整攻略。

什么是@Transactional注解?

@Transactional是Spring框架中用于实现事务管理的注解。在一个被该注解标注的方法或类上使用该注解,可以使得这个方法或类变为一个事务处理的方法或类,在这个方法或类的执行过程中,会同步进行数据源的事务管理。

@Transactional注解的属性

在使用@Transactional注解时,可以指定以下属性来控制事务的管理。

  • propagation:事务的传播行为,默认值为REQUIRED。包括以下传播行为:
  • REQUIRED:表示当前方法必须在事务内执行,如果当前上下文中已经有了事务,当前方法就在这个事务内执行,否则就开启一个新的事务。
  • REQUIRES_NEW:表示当前方法必须在新的事务内执行,如果当前上下文中已经有了事务,就将该事务挂起,当前方法在新的事务内执行。
  • SUPPORTS:表示当前方法支持事务,但可以继承上下文中的事务(如果有)。
  • NOT_SUPPORTED:表示当前方法不支持事务,如果存在事务就将其挂起。
  • MANDATORY:表示当前方法必须在事务内执行,如果当前上下文中没有事务,就抛出异常。
  • NEVER:表示当前方法不能在事务内执行,如果当前上下文中有事务就抛出异常。
  • NESTED:表示当前方法必须在另一个事务内执行,当前方法创建一个新的保存点,并只对这个保存点回滚。

  • isolation:事务的隔离级别,默认值为DEFAULT,包括以下隔离级别:

  • DEFAULT:表示使用底层数据源的默认隔离级别。
  • READ_COMMITTED:表示事务中操作的数据,只要已经提交,就可以被另一个事务读取,可避免脏读现象。
  • READ_UNCOMMITTED:表示无法解决脏读、不可重复读、幻读的问题,不应该在生产环境中使用。
  • REPEATABLE_READ:表示事务中操作的数据,只有在当前事务之前已经被锁定,才能被当前事务访问,可避免脏读和不可重复读现象。
  • SERIALIZABLE:表示所有事务必须依次进行,且不能并发执行。

  • timeout:事务的超时时间,默认值为-1,单位为秒。

  • readOnly:表明事务是否为只读事务,默认值为false。

  • rollbackFor:异常类数组,当出现异常时,事务就会回滚。

  • noRollbackFor:异常类数组,当出现这些异常时,事务不会回滚。

@Transactional在方法上的使用方法

在方法上使用@Transactional注解时,需要在方法声明上加上该注解。例如:

@Transactional
public void saveUser(User user) {
    userDao.save(user);
}

上面的代码中,saveUser方法在执行时,如果之前还没有开启事务,就会自动开启一个事务;如果当前的方法已经在一个开启的事务内,保存操作将会在该事务内完成;如果该方法执行成功,事务就会被提交,如果其中有一个或多个操作失败,则整个事务会被回滚,所有变更将会被撤回。

@Transactional在类上的使用方法

在类上使用@Transactional注解时,该注解会应用到所标注的类中的所有方法中。例如:

@Transactional
@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserDao userDao;

    @Override
    public void saveUser(User user) {
        userDao.save(user);
    }

    @Override
    public void updateUser(User user) {
        userDao.update(user);
    }
}

上面的代码中,@Transactional注解标注在了类上,是该类中的所有方法都会受到其影响,如果该类中的任意一个方法当中出现了异常,那么在这个事务的生命周期内,所有未提交的更改都将被回滚。

示例1:事务的嵌套

@Transactional
@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserDao userDao;

    @Override
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void saveUser(User user) {
        userDao.save(user);
    }

    @Override
    public void updateUser(User user) {
        userDao.update(user);
        // 保存其它业务数据
        try {
            saveOtherData();
        } catch(Exception e) {
            throw new RuntimeException("保存其它业务数据失败", e);
        }
    }

    // 保存其它业务数据
    private void saveOtherData() {
        // do something
    }
}

上面的代码中,saveUser方法的事务传播行为为REQUIRES_NEW,表示该方法已经开启了一个新的事务;在updateUser方法中调用了saveOtherData方法,该方法会在当前事务中执行,如果保存数据失败了,就会抛出异常。此时,该异常会被抛到updateUser方法中,因为该方法在一个已经开启的事务中执行,整个事务就会被回滚,而saveUser方法开启的事务并不受updateUser方法的回滚影响,依然会在数据源中保存成功。

示例2:基于异常回滚

@Transactional
@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserDao userDao;

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public void saveUser(User user) {
        userDao.save(user);
        if (StringUtils.isBlank(user.getNickname())) {
            throw new RuntimeException("昵称不能为空");
        }
    }

    @Override
    public void updateUser(User user) {
        userDao.update(user);
    }
}

上面的代码中,saveUser方法的事务标注了rollbackFor属性,表示只有当该方法抛出RuntimeException时,才会回滚整个方法的所有更改。如果在该方法中执行了若干操作,但其中只有一项出现了问题,其它操作都执行成功了,即使抛出了异常,也只会回滚该方法中失败的操作,而其它成功的操作并不会被回滚。这样就可以避免因为某些无关紧要的操作导致整个事务全部回滚,提高了数据操作的准确性。

阅读剩余 68%

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:spring的@Transactional注解用法解读 - Python技术站

(0)
上一篇 2023年5月20日
下一篇 2023年5月20日

相关文章

  • Nginx使用limit_req_zone对同一IP访问进行限流的方法

    下面将详细讲解“Nginx使用limit_req_zone对同一IP访问进行限流的方法”攻略。 简介 随着Web应用规模的不断增大和用户量的不断增多,对Web服务器的并发访问压力也越来越大。Nginx是一款高性能、高稳定性、低资源占用的Web服务器,常用于处理高并发请求。但在高并发情况下,同一IP对服务器的请求过多可能会引发服务器压力过大从而导致服务器响应缓…

    Java 2023年6月15日
    00
  • java中stringBuilder的用法详解

    下面就为大家详细讲解“java中StringBuilder的用法详解”的完整攻略。 什么是StringBuilder 在Java中,StringBuilder是一个可以修改的字符串,提供了很多操作字符串的方法,比如添加字符、插入字符、删除字符等。StringBuilder和String之间最大的不同是StringBuilder是可变的,而String是不可变…

    Java 2023年5月26日
    00
  • Kafka的监听地址配置实例详解

    我们来详细讲解一下“Kafka的监听地址配置实例详解”。 什么是Kafka的监听地址 在Kafka中,监听地址指的是Kafka Broker节点监听网络请求的IP地址和端口号。Kafka提供三种不同的通信协议,分别是PLAINTEXT,SSL和SASL_PLAINTEXT。在配置监听地址时,需要确保Kafka Broker节点能够在其IP地址和端口号上接收来…

    Java 2023年5月20日
    00
  • 深入解析kafka 架构原理

    当我们使用 Apache Kafka 作为消息中心时,需要了解它的架构原理,以便更好地在应用程序中使用它。 Kafka 架构 Kafka 是一个分布式发布订阅消息系统。它的主要组件包括: Broker – 处理传入和传出的消息并维护消息的存储 Topic – 是发布和订阅消息的名称 Partition – 一个主题可能被分成多个分区。每个分区都是一个有序的,…

    Java 2023年6月2日
    00
  • maven profile动态选择配置文件详解

    下面是本人为你准备的maven profile动态选择配置文件的攻略,希望能帮助到你。 什么是maven profile Maven Profile是Maven中的一个重要概念,它定义了一组配置的集合,用来指定开发、测试和生产环境下使用不同的配置。通过设置不同的Profile,可以实现在不同环境下对应用程序的多个设置的更改。 Maven Profile的配置…

    Java 2023年6月2日
    00
  • IDEA生成可运行jar包(包含第三方jar包)流程详解

    下面是”IDEA生成可运行jar包(包含第三方jar包)流程详解”的完整攻略: 一、前置条件 在进行下面的步骤之前,必须确保满足以下条件: 安装了Java开发工具包(JDK) 安装了IntelliJ IDEA开发环境 确保本地已经存在可运行程序的代码 二、生成可运行jar包 1. 配置Maven 在IntelliJ IDEA中打开Maven Projects…

    Java 2023年5月19日
    00
  • JavaWeb开发入门第一篇必备知识讲解

    关于“JavaWeb开发入门第一篇必备知识讲解”的完整攻略,下面是详细的说明: JavaWeb开发入门第一篇必备知识讲解 什么是JavaWeb? JavaWeb是Java语言在Web应用程序领域中的应用,主要包括Servlet、JSP、Web服务等技术。JavaWeb技术架构主要是基于MVC思想,即模型(M)-视图(V)-控制器(C)。 Servlet Se…

    Java 2023年5月30日
    00
  • Java8优雅的字符串拼接工具类StringJoiner实例代码

    下面是关于“Java8优雅的字符串拼接工具类StringJoiner实例代码”的完整攻略。 什么是StringJoiner StringJoiner是Java 8中提供的一个字符串拼接工具类。它可以将多个字符串按照指定的分隔符连接起来,并可以指定前缀和后缀,从而生成一个完整的字符串。 StringJoiner的构造方法 public StringJoiner…

    Java 2023年5月26日
    00
合作推广
合作推广
分享本页
返回顶部