Spring之路(39)–基于TransactionTemplate的编程式事务管理

简介: 本文目录1. 背景2. 代码实现

1. 背景

上一篇实现的基于PlatformTransactionManater的编程式事务管理,是属于非常低级的封装,其实就是将原来的JDBC事务操作封装为一个接口而已,然后由具体的实现类来实现。


本篇通过TransactionTemplate类,实现了对固定流程代码的封装,只需要将视作原子性操作的几个数据库操作放入一个方法中处理即可实现事务。


2. 代码实现

修改配置类,在上一篇注册PlatformTransactionManater类型bean的基础上,注册TransactionTemplate类型的bean,代码如下:

package org.maoge.templatetran;
import javax.sql.DataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.support.TransactionTemplate;
import com.alibaba.druid.pool.DruidDataSource;
/**
* Spring配置类
*/
@Configuration
public class SpringConfig {
   /**
    * 定义数据源bean
    */
   @Bean
   public DataSource dataSource() {
    DruidDataSource dataSource = new DruidDataSource();
    dataSource.setDriverClassName("com.mysql.jdbc.Driver");
    dataSource.setUrl("jdbc:mysql://127.0.0.1:3306/myblog?useUnicode=true&characterEncoding=utf-8");
    dataSource.setUsername("root");
    dataSource.setPassword("Easy@0122");
    return dataSource;
   }
   /**
    * 定义事务管理bean
    */
   @Bean
   public PlatformTransactionManager transactionManager() {
    DataSourceTransactionManager transactionManager = new DataSourceTransactionManager();
    transactionManager.setDataSource(dataSource());// 注入dataSource
    return transactionManager;
   }
   /**
    * 定义TransactionTemplate类型的bean
    */
   @Bean
   public TransactionTemplate transactionTemplate() {
    TransactionTemplate transactionTemplate=new TransactionTemplate();
    transactionTemplate.setTransactionManager(transactionManager());//注入事务管理器
    return transactionTemplate;
   }
   /**
    * 配置namedParameterJdbcTemplate组件
    */
   @Bean
   public NamedParameterJdbcTemplate namedParameterJdbcTemplate() {
    NamedParameterJdbcTemplate template = new NamedParameterJdbcTemplate(dataSource());// 注入dataSource
    return template;
   }
   /**
    * 为BlogDao注册bean
    */
   @Bean
   public BlogDao blogDao() {
    BlogDao blogDao = new BlogDao();
    blogDao.setNamedTemplate(namedParameterJdbcTemplate());// 注入namedParameterJdbcTemplate
    return blogDao;
   }
}

数据对象BlogDo和数据操作对象BlogDao没有任何变化:

package org.maoge.templatetran;
import java.util.HashMap;
import java.util.Map;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
/**
* @theme DAO--博客
* @author maoge
* @date 2020-01-29
*/
public class BlogDao {
   public NamedParameterJdbcTemplate getNamedTemplate() {
    return namedTemplate;
   }
   public void setNamedTemplate(NamedParameterJdbcTemplate namedTemplate) {
    this.namedTemplate = namedTemplate;
   }
   private NamedParameterJdbcTemplate namedTemplate;
   /**
    * 新增
    */
   public void insert(BlogDo blog) {
    Map<String, Object> map = new HashMap<>();
    map.put("author", blog.getAuthor());
    map.put("content", blog.getContent());
    map.put("title", blog.getTitle());
    // 注意使用:xxx占位
    namedTemplate.update("insert into blog(author,content,title)values(:author,:content,:title)", map);
   }
}
package org.maoge.templatetran;
/**
 * @theme 数据对象--博客
 * @author maoge
 * @date 2020-01-27
 */
public class BlogDo {
  private Long id;
  private String title;
  private String author;
  private String content;
  // 省略get get
}
测试验证,注意使用事务时,通过TransactionTemplate类的方法使用:
package org.maoge.templatetran;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;
public class Main {
  public static void main(String[] args) {
    // 获取容器
    AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
    // 容器中获取TransactionTemplate
    TransactionTemplate transactionTemplate = (TransactionTemplate) context.getBean("transactionTemplate");
    // 容器中获取数据库操作组件
    BlogDao blogDao = (BlogDao) context.getBean("blogDao");
    transactionTemplate.execute(new TransactionCallbackWithoutResult() {
      // 注意!该方法中的操作会实现事务
      @Override
      protected void doInTransactionWithoutResult(TransactionStatus arg0) {
        BlogDo blog = new BlogDo();
        blog.setContent("测试");
        blogDao.insert(blog);
        int a = 1 / 0;// 发生异常,导致事务回滚,所以并不会插入任何一行数据
        blogDao.insert(blog);
      }
    });
  }
}

需要注意的是,TransactionTemplate执行时,不论发生受检查的异常(Exception),还是不受检查的异常(RuntimeException),均会执行回滚操作,这个是比较符合我们期望的,在下一篇声明式事务管理里面,你会发现默认情况不是这样的,有点小坑啊。

相关文章
|
26天前
|
Java Spring
一键注入 Spring 成员变量,顺序编程
介绍了一款针对Spring框架开发的插件,旨在解决开发中频繁滚动查找成员变量注入位置的问题。通过一键操作(如Ctrl+1),该插件可自动在类顶部添加`@Autowired`注解及其成员变量声明,同时保持光标位置不变,有效提升开发效率和代码编写流畅度。适用于IntelliJ IDEA 2023及以上版本。
一键注入 Spring 成员变量,顺序编程
|
2月前
|
XML Java 数据库连接
Spring高手之路25——深入解析事务管理的切面本质
本篇文章将带你深入解析Spring事务管理的切面本质,通过AOP手动实现 @Transactional 基本功能,并探讨PlatformTransactionManager的设计和事务拦截器TransactionInterceptor的工作原理,结合时序图详细展示事务管理流程,最后引导分析 @Transactional 的代理机制源码,帮助你全面掌握Spring事务管理。
39 2
Spring高手之路25——深入解析事务管理的切面本质
|
3月前
|
Java Spring 容器
Spring IOC、AOP与事务管理底层原理及源码解析
【10月更文挑战第1天】Spring框架以其强大的控制反转(IOC)和面向切面编程(AOP)功能,成为Java企业级开发中的首选框架。本文将深入探讨Spring IOC和AOP的底层原理,并通过源码解析来揭示其实现机制。同时,我们还将探讨Spring事务管理的核心原理,并给出相应的源码示例。
152 9
|
3月前
|
Java 数据库连接 Spring
【2021Spring编程实战笔记】Spring开发分享~(下)
【2021Spring编程实战笔记】Spring开发分享~(下)
37 1
|
3月前
|
XML Java 数据库连接
【2020Spring编程实战笔记】Spring开发分享~(上)
【2020Spring编程实战笔记】Spring开发分享~
61 0
|
4月前
|
Java 数据库连接 数据库
Spring基础3——AOP,事务管理
AOP简介、入门案例、工作流程、切入点表达式、环绕通知、通知获取参数或返回值或异常、事务管理
|
5月前
|
XML Java 数据格式
Spring5入门到实战------11、使用XML方式实现AOP切面编程。具体代码+讲解
这篇文章是Spring5框架的AOP切面编程教程,通过XML配置方式,详细讲解了如何创建被增强类和增强类,如何在Spring配置文件中定义切入点和切面,以及如何将增强逻辑应用到具体方法上。文章通过具体的代码示例和测试结果,展示了使用XML配置实现AOP的过程,并强调了虽然注解开发更为便捷,但掌握XML配置也是非常重要的。
Spring5入门到实战------11、使用XML方式实现AOP切面编程。具体代码+讲解
|
5月前
|
XML Java 数据库
Spring5入门到实战------15、事务操作---概念--场景---声明式事务管理---事务参数--注解方式---xml方式
这篇文章是Spring5框架的实战教程,详细介绍了事务的概念、ACID特性、事务操作的场景,并通过实际的银行转账示例,演示了Spring框架中声明式事务管理的实现,包括使用注解和XML配置两种方式,以及如何配置事务参数来控制事务的行为。
Spring5入门到实战------15、事务操作---概念--场景---声明式事务管理---事务参数--注解方式---xml方式
|
5月前
|
Java Spring XML
掌握面向切面编程的秘密武器:Spring AOP 让你的代码优雅转身,横切关注点再也不是难题!
【8月更文挑战第31天】面向切面编程(AOP)通过切面封装横切关注点,如日志记录、事务管理等,使业务逻辑更清晰。Spring AOP提供强大工具,无需在业务代码中硬编码这些功能。本文将深入探讨Spring AOP的概念、工作原理及实际应用,展示如何通过基于注解的配置创建切面,优化代码结构并提高可维护性。通过示例说明如何定义切面类、通知方法及其应用时机,实现方法调用前后的日志记录,展示AOP在分离关注点和添加新功能方面的优势。
74 0
|
5月前
|
Java Spring 容器
彻底改变你的编程人生!揭秘 Spring 框架依赖注入的神奇魔力,让你的代码瞬间焕然一新!
【8月更文挑战第31天】本文介绍 Spring 框架中的依赖注入(DI),一种降低代码耦合度的设计模式。通过 Spring 的 DI 容器,开发者可专注业务逻辑而非依赖管理。文中详细解释了 DI 的基本概念及其实现方式,如构造器注入、字段注入与 setter 方法注入,并提供示例说明如何在实际项目中应用这些技术。通过 Spring 的 @Configuration 和 @Bean 注解,可轻松定义与管理应用中的组件及其依赖关系,实现更简洁、易维护的代码结构。
72 0