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 前言 ...
随机推荐
- 《Effective Java》 读书笔记(六)避免创建不必要的对象
java 有很多修饰类的属性的关键字:常用的static,final 说说final和static吧,平时在编程的时候,这两个关键字很多时候都觉得可有可无,最多的时候就是他们俩同时出现----定义常量 ...
- 爬虫之request库主要解析---参照慕课北理工嵩天
kv = {'key1':'value1','key2':'value2'} r = requests.request (' GET' , 'http://python123.io/ws' , par ...
- 最新JetBrainsPyCharm自动部署Python(Django,tornado等)项目至远程服务器
每次开发Python项目时,对于所有Python开发人员来说,最枯燥的不是修改代码,而是实时将自己的代码上传至远程服务器,进行测试或者部署,本人最初开发也是这样,通过使用Xshell 5,WinSCP ...
- python——inspect模块
inspect模块常用功能 import inspect # 导入inspect模块 inspect.isfunction(fn) # 检测fn是不是函数 inspect.isgenerator((x ...
- python中实例方法,类方法,静态方法简单理解
按照字面名称来理解的话: 实例方法就是实例化对象的方法,绑定在实例对象上 类方法就是类自己的方法,不需要实例化对象,类自己就是对象,直接绑定在类上 静态方法就是普通的函数,函数作为对象,不过是封装在类 ...
- python手册学习笔记1
笔记1 > http://www.pythondoc.com/pythontutorial3/controlflow.html 参数传递 Python中sys.argv的用法 调用解释器时,脚本 ...
- 使用requests实现人人网登录,并做cookie维持
import requests import re,time s = requests.Session() def doLogin(): login_url = 'http://www.renren. ...
- python中字符串常见操作(二)
# 可迭代对象有:字典,列表,元组,字符串,集合 str1 = '192.168.1.1' str2 = 'as df gh jk' str3 = '小李子' str4 = ['aa','bb','c ...
- pssh系列工具
一.pssh简介及安装 首先我们来了解下什么是pssh,它是干嘛用的?pssh是一个python编写可以在多台服务器上执行命令的工具,也可以实现文件复制.换而言之就是一个批量管理多台服务器的一个小工具 ...
- WPF CefSharp 爬虫
1.实际需求 EMS邮件的自动分拣,要分拣首先需要获取邮件的面单号和邮寄地址,现在我们的快递一般都有纸质面单的,如果是直接使用图像识别技术从纸质面单中获取信息,这个开发的成本和实时性 ...