深入理解TransactionTemplate编程式事务
Spring可以支持编程式事务和声明式事务。
Spring提供的最原始的事务管理方式是基于TransactionDefinition、PlatformTransactionManager、TransactionStatus 编程式事务。
而TransactionTemplate的编程式事务管理是使用模板方法设计模式对原始事务管理方式的封装。
源码探索
查看 TransactionTemplate.java 源码
public class TransactionTemplate extends DefaultTransactionDefinition implements TransactionOperations, InitializingBean {
protected final Log logger = LogFactory.getLog(this.getClass());
private PlatformTransactionManager transactionManager;
public TransactionTemplate() {
}
public TransactionTemplate(PlatformTransactionManager transactionManager) {
this.transactionManager = transactionManager;
}
public TransactionTemplate(PlatformTransactionManager transactionManager, TransactionDefinition transactionDefinition) {
super(transactionDefinition);
this.transactionManager = transactionManager;
}
public void setTransactionManager(PlatformTransactionManager transactionManager) {
this.transactionManager = transactionManager;
}
public PlatformTransactionManager getTransactionManager() {
return this.transactionManager;
}
public void afterPropertiesSet() {
if (this.transactionManager == null) {
throw new IllegalArgumentException("Property 'transactionManager' is required");
}
}
/*
* 控制事务管理主要依赖于这个方法
*/
public <T> T execute(TransactionCallback<T> action) throws TransactionException {
if (this.transactionManager instanceof CallbackPreferringPlatformTransactionManager) {
return ((CallbackPreferringPlatformTransactionManager)this.transactionManager).execute(this, action);
} else {
TransactionStatus status = this.transactionManager.getTransaction(this);
Object result;
try {
result = action.doInTransaction(status);
} catch (RuntimeException var5) {
this.rollbackOnException(status, var5);
throw var5;
} catch (Error var6) {
this.rollbackOnException(status, var6);
throw var6;
} catch (Exception var7) {
this.rollbackOnException(status, var7);
throw new UndeclaredThrowableException(var7, "TransactionCallback threw undeclared checked exception");
}
this.transactionManager.commit(status);
return (T) result;
}
}
private void rollbackOnException(TransactionStatus status, Throwable ex) throws TransactionException {
this.logger.debug("Initiating transaction rollback on application exception", ex);
try {
this.transactionManager.rollback(status);
} catch (TransactionSystemException var4) {
this.logger.error("Application exception overridden by rollback exception", ex);
var4.initApplicationException(ex);
throw var4;
} catch (RuntimeException var5) {
this.logger.error("Application exception overridden by rollback exception", ex);
throw var5;
} catch (Error var6) {
this.logger.error("Application exception overridden by rollback error", ex);
throw var6;
}
}
}
从源码可以看出TransactionTemplate主要依赖于execute(TransactionCallback<T> action)方法执行事务管理。
再来分析分析execute方法的参数 TransactionCallback
查看接口TransactionCallback.java 发现其仅有一个方法:
public interface TransactionCallback<T> {
T doInTransaction(TransactionStatus var1);
}
并且有一个抽象类TransactionCallbackWithoutResult实现了接口TransactionCallback。
public abstract class TransactionCallbackWithoutResult implements TransactionCallback<Object> {
public TransactionCallbackWithoutResult() {
}
public final Object doInTransaction(TransactionStatus status) {
this.doInTransactionWithoutResult(status);
return null;
}
protected abstract void doInTransactionWithoutResult(TransactionStatus var1);
}
所以当我们借助TransactionTemplate.execute( ... )执行事务管理的时候,传入的参数有两种选择:
1、TransactionCallback
2、TransactionCallbackWithoutResult
两种区别从命名看就相当明显了,一个是有返回值,一个是无返回值。这个的选择就取决于你是读还是写了。
实现案例
1、在spring配置文件中配置相关TransactionTemplate示例:
<!-- 事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- 配置 transactionTemplate -->
<bean id="transactionTemplate"
class="org.springframework.transaction.support.TransactionTemplate">
<property name="transactionManager">
<ref bean="transactionManager"/>
</property>
</bean>
2、对TransactionCallback进行属性设置(该设置也可以在Spring的配置文件中指定,看个人需求)
//设置事务传播属性
transactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
// 设置事务的隔离级别,设置为读已提交(默认是ISOLATION_DEFAULT:使用的是底层数据库的默认的隔离级别)
transactionTemplate.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED);
// 设置是否只读,默认是false
transactionTemplate.setReadOnly(true);
// 默认使用的是数据库底层的默认的事务的超时时间
transactionTemplate.setTimeout(30000);
3、业务代码引用:
(1)借助(TransactionCallback)执行事务管理,既带有返回值:
public Object getObject(String str) {
/*
* 执行带有返回值<Object>的事务管理
*/
transactionTemplate.execute(new TransactionCallback<Object>() {
@Override
public Object doInTransaction(TransactionStatus transactionStatus) {
try {
...
//....... 业务代码
return new Object();
} catch (Exception e) {
//回滚
transactionStatus.setRollbackOnly();
return null;
}
}
});
}
(2)借助(TransactionCallbackWithoutResult)执行事务管理,既无返回值:
public void update(String str) {
/*
* 执行无返回值的事务管理
*/
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {
try {
// .... 业务代码
} catch (Exception e){
//回滚
transactionStatus.setRollbackOnly();
}
}
});
}
深入理解TransactionTemplate编程式事务的更多相关文章
- Spring事务管理的另一种方式--TransactionTemplate编程式事务管理简单入门
1, 一直以来, 在用Spring进行事物管理时, 只知道用声明式的策略, 即根据不同的数据源, 配置一个事物管理器(TransactionManager), 通过配置切面(PointCut)应用到相 ...
- TransactionTemplate编程式事务管理方式的进阶使用---自定义拓展模板类
1, 前面一篇的文章介绍了TransactionTemplate的基本使用方法. 同事在其基础上又做了一层封装,这样更贴合本公司的业务与规范. 2, 首先定义了两个接口: ServiceTemplat ...
- 全面分析 Spring 的编程式事务管理及声明式事务管理
开始之前 关于本教程 本教程将深入讲解 Spring 简单而强大的事务管理功能,包括编程式事务和声明式事务.通过对本教程的学习,您将能够理解 Spring 事务管理的本质,并灵活运用之. 先决条件 本 ...
- spring 编程式事务管理和声明式事务管理
编程式事务管理 Spring 的编程式事务管理概述 在 Spring 出现以前,编程式事务管理对基于 POJO 的应用来说是唯一选择.用过 Hibernate 的人都知道,我们需要在代码中显式调用be ...
- 全面分析 Spring 的编程式事务管理及声明式事务管理--转
开始之前 关于本教程 本教程将深入讲解 Spring 简单而强大的事务管理功能,包括编程式事务和声明式事务.通过对本教程的学习,您将能够理解 Spring 事务管理的本质,并灵活运用之. 先决条件 本 ...
- spring事务管理——编程式事务、声明式事务
本教程将深入讲解 Spring 简单而强大的事务管理功能,包括编程式事务和声明式事务.通过对本教程的学习,您将能够理解 Spring 事务管理的本质,并灵活运用之. 先决条件 本教程假定您已经掌握了 ...
- Spring编程式事务管理及声明式事务管理
本文将深入讲解 Spring 简单而强大的事务管理功能,包括编程式事务和声明式事务.通过对本教程的学习,您将能够理解 Spring 事务管理的本质,并灵活运用之. Spring 事务属性分析 事务管理 ...
- Spring笔记(4) - Spring的编程式事务和声明式事务详解
一.背景 事务管理对于企业应用而言至关重要.它保证了用户的每一次操作都是可靠的,即便出现了异常的访问情况,也不至于破坏后台数据的完整性.就像银行的自助取款机,通常都能正常为客户服务,但是也难免遇到操作 ...
- Spring 声明式事务与编程式事务详解
本文转载自IBM开发者论坛:https://developer.ibm.com/zh/articles/os-cn-spring-trans 根据自己的学习理解有所调整,用于学习备查. 事务管理对于企 ...
随机推荐
- 【VS开发】CTabView多页卡界面
转载地址:http://blog.csdn.net/akof1314/article/details/5618454 目录(?)[-] Public Methods Protected Methods ...
- ubuntu下不能访问docker中的rabbitmq服务端口
主要原因是防火墙屏蔽了15672端口,宿主机就不能直接通过 ip:port的形式访问rabbitmq的管理界面了. 解决方法很简单: 设置防火墙规则,使外部主机能够访问虚拟机的15672端口. 启动i ...
- elasticsearch 常用查询 + 删除索引 + 集群状态诊断
1.多条件查询 curl -X POST \ http://10.0.0.42:9200/addressbook_user/_search \ -H 'cache-control: no-cache' ...
- 11.把文本文件的数据导入到Hive表中
先在hive里面创建一个表 create table mydb2.t3(id int,name string,age int) row format delimited fields terminat ...
- [转帖]传输层安全协议TLS 1.3 RFC 8446使互联网更快、更安全
传输层安全协议TLS 1.3 RFC 8446使互联网更快.更安全 2018-08-12 11:38:19作者:LINUX人稿源:开源社区 https://ywnz.com/linuxyffq/261 ...
- Oracle的基本操作-序列的使用
序列:默认从1开始,一次递增,主要用来给主键赋值使用 create sequence s_person; select s_person.nextval from dual; --dual是一张虚表, ...
- 免费ip共享库
分享一个免费的ip地址库查询,同时支持ipv4和ipv6查询,提供api接口.官网地址:https://www.calpha.club/ 希望可以帮助运维朋友们. python 2.7实例# -*- ...
- mybatis-plus 错误 java.lang.NoClassDefFoundError
错误 java.lang.NoClassDefFoundError: org/apache/velocity/context/Context 使用mybatis-plus自动生成文件的时候,报下面的错 ...
- Linux系列(10):入门之bash基础与bash环境设置
了解什么是shell吗? 知道如何查询当前系统支持的shell版本吗? 了解如何判断某个指令是否是bash的内置指令吗? 了解Linux的变量吗,知道如何定义与删除变量吗,知道如何赋值吗,知道如何获取 ...
- 使用rpm安装mysql 5.7和依赖们
在安装mysql-server之前,需要安装相应的依赖,当前系统环境是CentOS7,需要安装3个依赖,mysql-community-common,mysql-community-libs,mysq ...