Spring 框架基础(05):事务管理机制,和实现方式
本文源码:GitHub·点这里 || GitEE·点这里
一、Spring事务管理
1、基础描述
Spring事务管理的本质就是封装了数据库对事务支持的操作,使用JDBC的事务管理机制,就是利用java.sql.Connection对象完成对事务的提交和回滚。
Connection conn = DriverManager.getConnection();
try {
// 自动提交设置为false
conn.setAutoCommit(false);
// 执行增删改查操作
// 当操作成功后手动提交
conn.commit();
} catch (Exception e) {
// 出现异常,回滚所有操作
conn.rollback();
e.printStackTrace();
} finally {
conn.colse();
}
2、事务常见概念
- 事务
事务是指作为单个逻辑工作单元执行的一系列操作(SQL语句)。这些操作要么全部成功,要么全部不成功。
- 特性:ACID
原子性(Atomicity):事务中的多个操作要么都成功要么都失败
一致性(consistency):事务的执行的前后数据的完整性保持一致
隔离性(isolation):事务执行的过程中,不应该受到其他事务的干扰
持久性(durability):事务一旦结束,数据就持久到数据库
- 隔离问题
脏读:一个事务读到另一个事务没有提交的数据
不可重复读:一个事务前后多次读取相同数据,数据内容不一致,update场景问题
虚读(幻读):一个事务前后多次读取,数据总量不一致,insert场景问题
- 隔离级别
read uncommitted:
事务可以读取另一个未提交事务的数据。
read committed:
事务要等另一个事务提交后才能读取数据,解决脏读。
repeatable read:
在开始读取数据时,事务开启,不再允许修改操作,解决:脏读、不可重复读。
serializable:
最高事务隔离级别,事务串行化顺序执行,解决脏读、不可重复读、幻读。但是效率低下,耗数据库性能。
3、事务管理API描述
PlatformTransactionManager
平台事务管理器,Spring管理事务,必须使用事务管理器进行事务配置时,核心方法:获取事务,提交事务,回滚事务。
TransactionDefinition
该对象封装事务详情(事务定义、事务属性),例如:隔离级别、是否只读、超时时间 等。
TransactionStatus
用于记录当前事务运行状态。例如:是否有保存点,事务是否完成。Spring底层根据状态进行相应操作。
4、事务案例SQL语句
CREATE TABLE user_account(
id INT PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(50),
money INT
) ENGINE=InnoDB DEFAULT CHARSET=utf8;;
INSERT INTO user_account(username,money) VALUES('jack','5000');
INSERT INTO user_account(username,money) VALUES('tom','5000');
SELECT * FROM user_account ;
二、编程式事务管理
1、核心配置文件
<!-- 配置事物管理器 -->
<bean id="txManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<!-- 创建事物模板 -->
<bean id="transactionTemplate"
class="org.springframework.transaction.support.TransactionTemplate">
<property name="transactionManager" ref="txManager" />
</bean>
<!-- 配置转账接口 -->
<bean id="userAccountService"
class="com.spring.mvc.service.impl.UserAccountServiceImpl">
<property name="jdbcTemplate" ref="jdbcTemplate" />
<property name="transactionTemplate" ref="transactionTemplate" />
</bean>
2、演示案例
@Service
public class UserAccountServiceImpl extends JdbcDaoSupport implements UserAccountService {
// 注入事物模板
private TransactionTemplate transactionTemplate ;
public void setTransactionTemplate(TransactionTemplate transactionTemplate) {
this.transactionTemplate = transactionTemplate;
}
@Override
public void remittance(String remitTer, String receiver, int money) {
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
public void doInTransactionWithoutResult(TransactionStatus arg0) {
outMoney(remitTer,money);
// System.out.println(1/0);
innerMoney(receiver,money);
}
});
}
private void outMoney (String remitTer, int money){
String outSql = "update user_account set money = money - ? where username = ?";
this.getJdbcTemplate().update(outSql, money ,remitTer);
}
private void innerMoney (String receiver, int money){
String inSql = "update user_account set money = money + ? where username = ?";
this.getJdbcTemplate().update(inSql, money,receiver);
}
}
三、事务代理工厂
1、核心配置
<!-- 配置转账接口 -->
<bean id="userAccountService01"
class="com.spring.mvc.service.impl.UserAccountServiceImpl01">
<property name="jdbcTemplate" ref="jdbcTemplate" />
</bean>
<!-- 配置事务代理工厂 -->
<bean id="proxyAccountService"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="proxyInterfaces" value="com.spring.mvc.service.UserAccountService01" />
<property name="target" ref="userAccountService01" />
<property name="transactionManager" ref="txManager" />
<property name="transactionAttributes">
<props>
<!-- 默认传播行为、隔离级别 -->
<prop key="remittance">PROPAGATION_REQUIRED,ISOLATION_DEFAULT</prop>
<!-- 异常仍然提交事务
<prop key="remittance">PROPAGATION_REQUIRED,ISOLATION_DEFAULT,+java.lang.Exception</prop>
-->
</props>
</property>
</bean>
配置说明:
proxyInterfaces代理接口target代理目标类transactionManager事务管理器transactionAttributes事务属性(事务详情)prop.key指定方法使用当前事务配置
事务行为:
PROPAGATION传播行为ISOLATION隔离级别readOnly是否只读-Exception异常回滚+Exception异常提交
2、演示案例
@Service
public class UserAccountServiceImpl01 extends JdbcDaoSupport implements UserAccountService01 {
@Override
public void remittance(String remitTer, String receiver, int money) {
outMoney(remitTer,money);
System.out.println(1/0);
innerMoney(receiver,money);
}
private void outMoney (String remitTer, int money){
String outSql = "update user_account set money = money - ? where username = ?";
this.getJdbcTemplate().update(outSql, money ,remitTer);
}
private void innerMoney (String receiver, int money){
String inSql = "update user_account set money = money + ? where username = ?";
this.getJdbcTemplate().update(inSql, money,receiver);
}
}
3、测试代码
public class Tx_Test_02 {
@Test
public void test1 (){
String xmlPath = "spring-jdbc-tx-02.xml";
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(xmlPath);
UserAccountService01 accountService = (UserAccountService01)
context.getBean("proxyAccountService");
accountService.remittance("jack","tom",1000);
}
}
四、XML配置事务
首先配置事务管理器,然后配置事务属性,最后基于AOP编程配置事务切入点。
1、核心配置
<!-- 配置事物管理器 -->
<bean id="txManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<!-- 配置转账接口 -->
<bean id="userAccountService01"
class="com.spring.mvc.service.impl.UserAccountServiceImpl01">
<property name="jdbcTemplate" ref="jdbcTemplate" />
</bean>
<!-- 配置事物详情 -->
<tx:advice id="txAdvice" transaction-manager="txManager">
<tx:attributes>
<tx:method name="remittance"
propagation="REQUIRED"
isolation="DEFAULT"/>
</tx:attributes>
</tx:advice>
<!-- 事务切入点,基于AOP编程 -->
<aop:config>
<aop:advisor
advice-ref="txAdvice"
pointcut="execution(* com.spring.mvc.service.UserAccountService01.*(..))"/>
</aop:config>
五、基于事务注解
配置事务管理器,并启动事务注解的支持,在目标类或目标方法添加@Transactional核心注解即可。
1、核心配置
<!-- 配置事物管理器 -->
<bean id="txManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<!-- 支持事务注解 -->
<tx:annotation-driven transaction-manager="txManager" />
2、注解用法
注解写在接口方法上,或者接口实现的方法上效果一样。
public interface UserAccountService02 {
@Transactional(rollbackFor = Exception.class)
void remittance(String remitTer, String receiver, int money) ;
}
六、源代码地址
GitHub·地址
https://github.com/cicadasmile/spring-mvc-parent
GitEE·地址
https://gitee.com/cicadasmile/spring-mvc-parent

Spring 框架基础(05):事务管理机制,和实现方式的更多相关文章
- Spring框架——JDBC与事务管理
JDBC JDBCTemplate简介 XML配置JDBCTemplate 简化JDBC模板查询 事务管理 事务简介 Spring中的事务管理器 Spring中的事务管理器的不同实现 用事务通知声明式 ...
- Spring总结九:事务管理机制
何为事务 事务(Transaction),一般是指要做的或所做的事情.在计算机术语中是指访问并可能更新数据库中各种数据项的一个程序执行单元(unit).事务通常由高级数据库操纵语言或编程语言(如SQL ...
- 12 Spring框架 SpringDAO的事务管理
上一节我们说过Spring对DAO的两个支持分为两个知识点,一个是jdbc模板,另一个是事务管理. 事务是数据库中的概念,但是在一般情况下我们需要将事务提到业务层次,这样能够使得业务具有事务的特性,来 ...
- Spring 框架系列之事务管理
1.事务回顾 (1).什么是事务: 事务是逻辑上的一组操作,组成这组操作的各个逻辑单元,要么一起成功,要么一起失败. (2).事务特性(ACID) 原子性 :强调事务的不可分割 一致性 :事务的执行的 ...
- Spring Transaction + MyBatis SqlSession事务管理机制[marked]
- Spring入门5.事务管理机制
Spring入门5.事务管理机制 20131126 代码下载 : 链接: http://pan.baidu.com/s/1kYc6c 密码: 233t 回顾之前的知识,Spring 最为核心的两个部分 ...
- Spring事务管理机制的实现原理-动态代理
之前在做项目中遇到spring无法进行事务代理问题,最后发现是因为没有写接口,原因当时明白了,看到这篇文章写的清楚些,转过来 我们先来分析一下Spring事务管理机制的实现原理.由于Spring内置A ...
- spring 事务管理机制
1. spring 事务管理抽象 spring 的事务策略机制的核心就是 org.springframework.transaction.PlatformTransactionManager 接口. ...
- Spring入门6事务管理2 基于Annotation方式的声明式事务管理机制
Spring入门6事务管理2 基于Annotation方式的声明式事务管理机制 201311.27 代码下载 链接: http://pan.baidu.com/s/1kYc6c 密码: 233t 前言 ...
随机推荐
- API 接口开发规范
整体规范建议采用RESTful 方式来实施. 协议 API与用户的通信协议,总是使用HTTPs协议,确保交互数据的传输安全. 域名 应该尽量将API部署在专用域名之下.https://api.exam ...
- redis入门(三)
目录 redis入门(三) 目录 前言 事务 原理 Lua脚本 安装 脚本命令 集群搭建工具 redis-trib.rb redis官方集群搭建 集群横向扩展 故障转移 redis管理 参考文档 re ...
- js如何展示上传的图片
前言:本文章主要讲的是上传的图片如何展示在页面上. 一般来说,我们会先将本地图片上传到服务器,上传成功后,由后台返回图片的网络地址再在前端显示.但是,我今天讲的是不通过前面说的过程,而是直接使用js将 ...
- 使用Magicodes.SwaggerUI快速配置SwaggerUI以及设置API分组
Magicodes.SwaggerUI 快速配置和集成SwaggerUI 特点 通过配置文件简单配置即可完成SwaggerUI的API格式JSON生成和集成 支持API分组和隐藏 支持自定义页面和验证 ...
- Python进阶函数
一.函数的动态参数 之前我们说过了传参, 如果我们需要给一个函数传参, 而参数又是不确定的. 或者我给一个函数传很多参数, 我的形参就要写很多, 很麻烦, 怎么办呢. 我们可以考虑使用动态参数. 动态 ...
- 学习笔记39_EF的DAL层(精)
通用的分页查询 public IQueryable<UserInfo> GetPage<T>(int pageSize,int pageIndex,out int total, ...
- [考试反思]1002csp-s模拟测试56:凌乱
放假回来状态回升??(玩够了-但是稍困) T1打的不完全对,但是过掉了.很快的想到了二分吧喇叭啦.. 然后T2也挺快想出来了但是挂细节没发现,考试快结束的时候才发现出锅了. 改了过来是正解,但是出题人 ...
- visit:组合数学,ex_Lucas
没做过ex_Lucas的同学可以先看看这个:组合数学专题<礼物>题解.顺便把那道题水了. 有一个公式蛮重要的,竟然还有人不知道? 有一共n种共k个物品,每一种有a1,a2,a3...an个 ...
- P2860()
题目描述: 为了从F(1≤F≤5000)个草场中的一个走到另一个,贝茜和她的同伴们有时不得不路过一些她们讨厌的可怕的树.奶牛们已经厌倦了被迫走某一条路,所以她们想建一些新路,使每一对草场之间都会至少有 ...
- Apache服务及个人用户主页功能和密码验证
Apache服务程序中有个默认未开启的个人用户主页功能,能够为所有系统内的用户生成个人网站,确实很实用哦 第1步:开启个人用户主页功能: 1.vim /etc/httpd/conf.d/userdir ...