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时,才会回滚整个方法的所有更改。如果在该方法中执行了若干操作,但其中只有一项出现了问题,其它操作都执行成功了,即使抛出了异常,也只会回滚该方法中失败的操作,而其它成功的操作并不会被回滚。这样就可以避免因为某些无关紧要的操作导致整个事务全部回滚,提高了数据操作的准确性。

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

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

相关文章

  • 如何使用Java字节码插装工具?

    下面是使用Java字节码插装工具的完整攻略: 什么是Java字节码插装工具? Java字节码插装工具是一种工具,它能够在Java字节码层面上,对Java应用程序进行修改和增强,以实现一些原本不可能做到的功能,比如动态改变方法返回值、修改方法的行为、做AOP等。Java字节码插装工具常用的有ASM、Javassist、ByteBuddy等。 安装和配置Java…

    Java 2023年5月11日
    00
  • java Disruptor构建高性能内存队列使用详解

    Java Disruptor构建高性能内存队列使用详解 Java Disruptor是一个Java内存队列(Memory Queue)框架,其可以高效地实现并发数据交换,以及与其他多线程系统的数据交换。在高性能计算、高并发、大吞吐量等场景下能够发挥出非常好的性能。本文将详细介绍如何使用Java Disruptor构建高性能内存队列。 原理介绍 Disrupt…

    Java 2023年5月27日
    00
  • Java 事务详解及简单应用实例

    关于“Java 事务详解及简单应用实例”的完整攻略,下面我撰写一些内容,希望能够对您有所帮助。 Java 事务详解及简单应用实例 什么是事务 事务(Transaction)是指一个或多个操作组成的一个不可分割的执行单元。事务是数据库操作中的一个重要概念,它使得用户可以将多个操作看作一个整体完成,而不必担心它们之间的相互影响。 在Java中,事务必须在支持事务…

    Java 2023年5月19日
    00
  • SpringBoot 定制化返回数据的实现示例

    下面是关于「SpringBoot 定制化返回数据的实现示例」的完整攻略,包含以下内容: 背景介绍 基本思路 实现步骤 示例说明 背景介绍 在实际开发中,我们经常需要对接口返回数据进行定制化处理。例如,有时候我们需要统一的返回格式、或者在某些接口中需要添加额外的字段信息。这时候,我们就需要对 SpringBoot 中默认的返回数据进行定制化处理。 基本思路 S…

    Java 2023年5月26日
    00
  • 如何理解Java线程池及其使用方法

    如何理解Java线程池及其使用方法 什么是Java线程池 Java线程池是一种经过封装的多线程管理机制,通过该机制可以很方便地进行多线程编程。线程是一种稀缺资源,Java线程池可以通过对线程的管理来提高系统的运行效率,避免系统出现由于线程过多而抛出OutOfMemory异常的情况。 Java线程池中的每个线程都是一个独立的任务,这些任务将会被线程池统一管理,…

    Java 2023年5月18日
    00
  • SpringBoot如何整合mybatis-generator-maven-plugin 1.4.0

    下面我将为您讲解如何在Spring Boot项目中整合mybatis-generator-maven-plugin 1.4.0,供您参考。 1. 添加maven依赖 在pom.xml文件中添加mybatis-generator-maven-plugin 1.4.0的依赖,如下所示: <dependency> <groupId>org.…

    Java 2023年6月3日
    00
  • JSP页面中文参数的传递(get和post方法分析)

    关于JSP页面中文参数的传递,我们需要了解以下几点: JSP页面中传递参数的方式一般有两种:get方法和post方法。 为了避免中文乱码问题,我们在处理传递的参数时需要对字符编码进行设置。 对于get方法传递的参数,可以使用URLEncoder对中文进行编码,而在JSP页面接收时可以使用URLDecoder进行解码,即可得到原始中文字符串。 对于post方法…

    Java 2023年6月15日
    00
  • Java Exception 捕获和显示实例详解

    Java Exception 捕获和显示实例详解 什么是异常(Exception)? 在编写 Java 程序时,异常是不可避免的。异常是程序在运行时发生的错误或问题。 在 Java 中,异常被视为对象,这是由类派生的异常类的实例。 如果在运行程序时发生异常,程序会被终止。 Java 异常的类层次结构 在 Java 中,异常的类层次结构如下所示: java.l…

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