关于Spring中声明式事务的使用详解

yizhihongxing

关于Spring中声明式事务的使用详解

什么是声明式事务?

在Spring中,事务是指一组需要保证数据完整性和一致性的数据库操作。 在进行事务处理时,必须保证多个操作的原子性,即所有操作都能够全部成功或全部失败。

Spring中的声明式事务是基于AOP实现的,通过对方法进行拦截,在方法执行前后加上事务的开始和结束语句,来实现事务的管理。这样即使开发人员忘记在方法中手动添加事务的开始和结束语句,也可以确保方法能够在事务环境中执行,保证数据的完整性和一致性。

如何使用声明式事务?

配置文件中的声明式事务

在Spring中,我们可以在配置文件中通过<tx:advice><aop:config>标签声明式定义事务。下面是一个示例:

<bean id="userService" class="com.example.UserService" />

<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource"/>
</bean>

<tx:advice id="txAdvice" transaction-manager="txManager">
    <tx:attributes>
        <tx:method name="save" propagation="REQUIRED" rollback-for="Exception"/>
        <tx:method name="update" propagation="REQUIRED" rollback-for="Exception"/>
        <tx:method name="delete" propagation="REQUIRED" rollback-for="Exception"/>
        <tx:method name="*" propagation="SUPPORTS" read-only="true"/>
    </tx:attributes>
</tx:advice>

<aop:config>
    <aop:pointcut id="userServicePointcut" expression="execution(* com.example.UserService.*(..))"/>
    <aop:advisor advice-ref="txAdvice" pointcut-ref="userServicePointcut"/>
</aop:config>

上述代码中,我们首先声明了一个名为txManager的事务管理器,以管理使用Spring声明式事务的数据源。然后我们使用<tx:attributes>标签定义了事务传播机制、是否只读等Transaction Attributes信息,接着我们在<tx:advice>标签中引入刚才声明的事务管理器,并且将之前定义好的<tx:attributes>添加进去。最后使用<aop:config>标签进行切面配置,并在<aop:pointcut>标签中定义所需要拦截的方法,即com.example.UserService中的所有方法。最后通过<aop:advisor>标签将拦截器和切面关联起来。

在这个示例中,我们通过如上的配置,可以对UserService中的所有公有方法进行事务管理。当我们调用saveupdatedelete等写操作时,将会被Spring事务拦截并在方法执行前开启事务,在方法执行后进行事务提交或回滚。

使用注解的声明式事务

注解式事务是一种使用注解的方式声明事务的方式。相比于xml配置的方式,这种方式更加简洁明了。

@Service
public class UserService {
    @Autowired
    private UserDao userDao;

    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public void save(User user) throws Exception {
        userDao.save(user);
    }

    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public void update(User user) throws Exception {
        userDao.update(user);
    }

    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public void delete(Long userId) throws Exception {
        userDao.delete(userId);
    }

    @Transactional(rollbackFor = Exception.class, propagation = Propagation.SUPPORTS, readOnly = true)
    public User findUserById(Long userId) throws Exception {
        return userDao.findUserById(userId);
    }
}

上述代码中我们在UserService类中对方法进行了注解式事务的声明,通过@Transactional注解的propagation属性来确定事务传播机制,readOnly属性来指明方法是否为只读操作。我们还可以通过rollbackFornoRollbackFor属性来指明哪些异常需要回滚事务,哪些异常不需要回滚事务。

实例演示

在本次演示中,我们将使用Spring、MySQL和SpringMVC实现一个简单的增删改查功能。具体的示例代码参见https://github.com/LZxiaozhi/spring-transaction-demo

步骤

  1. 创建SpringMVC项目。
  2. 引入相关依赖。
  3. 在配置文件中配置MySQL数据源。
  4. 创建DAO层和Service层。
  5. 在Controller层中进行测试。

代码示例

  • 配置文件
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
    <property name="url" value="jdbc:mysql://localhost:3306/test?useSSL=false&amp;serverTimezone=UTC&amp;allowPublicKeyRetrieval=true"/>
    <property name="username" value="root"/>
    <property name="password" value="root"/>
</bean>

<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource"/>
</bean>

<tx:advice id="txAdvice" transaction-manager="txManager">
    <tx:attributes>
        <tx:method name="save" propagation="REQUIRED" rollback-for="Exception"/>
        <tx:method name="update" propagation="REQUIRED" rollback-for="Exception"/>
        <tx:method name="delete" propagation="REQUIRED" rollback-for="Exception"/>
        <tx:method name="*" propagation="SUPPORTS" read-only="true"/>
    </tx:attributes>
</tx:advice>

<aop:config>
    <aop:pointcut id="userServicePointcut" expression="execution(* com.example.service.*.*(..))"/>
    <aop:advisor advice-ref="txAdvice" pointcut-ref="userServicePointcut"/>
</aop:config>
  • Service层
@Service
public class UserService {
    @Autowired
    private UserDao userDao;

    public List<User> findAll() {
        return userDao.findAll();
    }

    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public void save(User user) throws Exception {
        userDao.add(user);
    }

    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public void update(User user) throws Exception {
        userDao.update(user);
    }

    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public void delete(Long id) throws Exception {
        userDao.delete(id);
    }
}
  • Controller层
@Controller
public class UserController {
    @Autowired
    private UserService userService;

    @GetMapping("/")
    public String index(Model model) {
        List<User> userList = userService.findAll();
        model.addAttribute("userList", userList);
        return "index";
    }

    @GetMapping("/add")
    public String add() {
        return "add";
    }

    @PostMapping("/add")
    public String save(User user) throws Exception {
        userService.save(user);
        return "redirect:/";
    }

    @GetMapping("/edit/{id}")
    public String edit(@PathVariable Long id, Model model) throws Exception {
        User user = userService.findById(id);
        model.addAttribute("user", user);
        return "edit";
    }

    @PostMapping("/edit/{id}")
    public String update(@PathVariable Long id, User user) throws Exception {
        user.setId(id);
        userService.update(user);
        return "redirect:/";
    }

    @GetMapping("/delete/{id}")
    public String delete(@PathVariable Long id) throws Exception {
        userService.delete(id);
        return "redirect:/";
    }
}

结论

在以上演示示例中,我们通过使用Spring中的声明式事务实现了数据的增删改查功能。

声明式事务的使用需要开发人员对AOP、事务传播机制等基本概念有一定的理解;在配置中需要注意propagationreadOnly等属性的值得合理配置;在实际应用中,我们可以通过注解和xml配置两种方式声明式的配置Spring事务。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:关于Spring中声明式事务的使用详解 - Python技术站

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

相关文章

  • Java字符串替换函数replace()用法解析

    Java字符串替换函数replace()用法解析 在Java中,我们常常需要对字符串进行替换操作。其中,最常用的就是 replace() 函数。本文将为你详细讲解 replace() 函数的使用方法和注意事项。 replace() 函数基本用法 replace() 函数的基本用法是:将原字符串中的某个字符或字符串替换成新的字符或字符串。 public Str…

    Java 2023年5月26日
    00
  • maven创建spark项目的pom.xml文件配置demo

    创建Spark项目的pom.xml文件是非常重要的一步,这个文件描述了项目的依赖和构建方式。 下面是一份简单的maven创建Spark项目的pom.xml文件配置攻略,其中包含了两个例子。 步骤1:创建Maven项目 在开始创建Spark项目的pom.xml文件之前,我们需要先创建一个Maven项目。可以通过使用maven命令行或者IDE来创建这个项目。 下…

    Java 2023年5月19日
    00
  • Java中反射的学习笔记分享

    关于Java中反射的学习笔记分享,下面就详细讲解一下完整攻略。 什么是Java中的反射 Java中的反射机制是指在运行时动态地获取一个类的各种信息的能力。它能够在程序运行时直接操作对象的内部属性,调用对象的方法,它使得原本在编译时就需要确定的类名、方法名等信息可以在运行时通过反射机制动态获取。 Java中反射的使用场景 1.在设计一些通用使用的代码时,比如动…

    Java 2023年5月26日
    00
  • 使用SpringBoot自定义starter的完整步骤

    使用SpringBoot自定义starter可以方便我们在多个项目中重复使用一些公共的依赖或配置。下面是使用SpringBoot自定义starter的完整步骤: 1. 创建maven项目 <groupId>com.example</groupId> <artifactId>custom-starter</artifa…

    Java 2023年5月15日
    00
  • 有关Java中的BeanInfo介绍

    一、BeanInfo是什么 BeanInfo是Java语言中一个专门为Java Bean设计的接口,用于操作Bean的元数据信息。BeanInfo主要描述了一个Java Bean的属性、方法、事件等信息,BeanInfo主要是为Java图形界面编辑器提供Bean对象的界面定制化功能而使用,其中面向对象的特性使得BeanInfo的属性信息更加具有灵活性。Bea…

    Java 2023年5月20日
    00
  • SQLite教程(七):数据类型详解

    下面是对 “SQLite教程(七):数据类型详解” 的完整攻略: 标题 SQLite教程(七):数据类型详解 内容 1. 数据类型 SQLite3 中包含了以下 5 种基本的数据类型: NULL 空值。 INTEGER 带符号的整型,具体取决于值的大小。 REAL 用于存储浮点数。 TEXT 用于存储字符串。 BLOB 用于存储二进制数据。 2. 示例 下面…

    Java 2023年5月26日
    00
  • PHP中auto_prepend_file与auto_append_file用法实例分析

    PHP中auto_prepend_file与auto_append_file用法实例分析 在PHP中,auto_prepend_file和auto_append_file是两个特殊的配置选项,它们分别用于在PHP脚本执行前和执行后自动执行指定的PHP脚本文件。这两个配置选项通常被用于实现一些公共功能或初始化操作。本文将详细讲解auto_prepend_fil…

    Java 2023年6月15日
    00
  • 使用Eclipse配置android开发环境教程

    使用Eclipse配置Android开发环境是一个比较基础的操作,本文将为大家提供一套完整的攻略,方便大家快速地开始Android开发。 步骤1:安装Java环境 在开始Android开发之前,需要先安装Java开发环境。具体可以按照以下步骤进行操作: 下载适合自己系统的JDK,推荐使用Oracle官网下载,网址为:https://www.oracle.co…

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