06-Spring03-事务管理
今日知识
1. Spring事务管理
2. 转账案例
Spring事务管理
1. 事务特性(ACID)
1. 原子性:整体 【原子性是指事务包含的所有操作要么全部成功,要么全部失败】
2. 一致性:数据 【一个事务执行之前和执行之后都必须处于一致性状态】
3. 隔离性:并发 【对于任意两个并发的事务T1和T2,在事务T1看来,T2要么在T1开始之前就已经结束,要么在T1结束之后才开始,这样每个事务都感觉不到有其他事务在并发地执行。】
4. 持久性:结果 【持久性是指一个事务一旦被提交了,那么对数据库中的数据的改变就是永久性的】
* 隔离问题
1. 脏读:一个事务读到另一个事务未提交的内容
2. 不可重复读:一个事务读到另一个事务已提交的内容(update)这是大多数数据库系统的默认隔离级别(但不是MySQL默认的)。它满足了隔离的简单定义:一个事务只能看见已经提交事务所做的改变。
3. 虚读:一个事务读到另一个事务已提交的内容(delete,insert),这是MySQL的默认事务隔离级别,它确保同一事务的多个实例在并发读取数据时,会看到同样的数据行。行数发生变化
4. Serializable(可串行化)
这是最高的隔离级别,它通过强制事务排序,使之不可能相互冲突,从而解决幻读问题。简言之,它是在每个读的数据行上加上共享锁。在这个级别,可能导致大量的超时现象和锁竞争。
* 隔离级别-解决问题
1. read uncommitted,读未提交,存在三个问题
2. read committed,读已提交,解决:脏读,存在两个问题
3. repeatable read,可重复读,解决:脏读,和不可重复读,存在一个问题
4. serializable,串行化。单事务。没有问题。一般不用,涉及IO操作,占用内存。
2. Spring提供的事务jar包
* spring-tx jar包
* jar 包包含三个顶级接口
* PlatformTransactionManager:
平台事务管理器,spring要管理事务,必须使用事务管理器,进行事务配置时,必须配置事务管理器
* TransactionDefinition:
事务详情(事务定义、事务属性),spring用于确定事务具体详情,
* TransactionStatus:
事务状态,spring用于记录当前事务运行状态。例如:是否有保存点,事务是否完成。
spring底层根据状态进行相应操作。
3. 手动代理事务
1. AccountServiceImpl写法注入TransactionTemplate
* public class AccountServiceImpl implements AccountService {
//spring底层使用 TransactionTemplate 事务模板进行操作。
//注入已经 配置事务模板
@Autowired
TransactionTemplate transactionTemplate;
//Spring注入AccountDao
@Autowired
AccountDao accountDao;
public void tansfer(final String inner, final String outer, final Integer money) {
//通过事务模板执行业务
this.transactionTemplate.execute(new TransactionCallbackWithoutResult() {
protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {
//第一个进账
accountDao.inner(inner,money);
//第二个出账
// int i=10/0;
accountDao.out(outer,money);
}
});
}
}
2. xml中的配置
* !--配置事务模板-->
<bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate">
<property name="transactionManager" ref="txManager"></property>
</bean>
<!--配置一个事务管理器-->
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager
">
<property name="dataSource" ref="dataSource"></property>
</bean>
4. 工厂bean生成代理事务:半自动
1. transactionAttributes:事务详情
prop.key :确定哪些方法使用当前事务配置
prop.text:用于配置事务详情
格式:PROPAGATION,ISOLATION,readOnly,-Exception,+Exception
传播行为 隔离级别 是否只读 异常回滚 异常提交
2. AccountServiceImpl2直接普通的写法,不用引入TransactionTemplate事务模板
3. xml中的配置
* <!--配置accountService2,bean-->
<bean id="accountService" class="com.rqy.service.impl.AccountServiceImpl2"/>
<!--配置管理事务的代理工厂,代替上面的方法,到达半自动代理-->
<bean id="proxyAccountService" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<!--配置接口-->
<property name="proxyInterfaces" value="com.rqy.service.AccountService"/>
<!--目标对象-->
<property name="target" ref="accountService"/>
<!--事务管理器-->
<property name="transactionManager" ref="txManager"/>
<!--事务详情-->
<!--
transactionAttributes:事务详情
prop.key :确定哪些方法使用当前事务配置
prop.text:用于配置事务详情
格式:PROPAGATION,ISOLATION,readOnly,-Exception,+Exception
传播行为 隔离级别 是否只读 异常回滚 异常提交
-->
<property name="transactionAttributes">
<props>
<prop key="transfer">PROPAGATION_REQUIRED,ISOLATION_REPEATABLE_READ</prop>
</props>
</property>
</bean>
<!--配置一个事务管理器-->
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager
">
<property name="dataSource" ref="dataSource"></property>
</bean>
基本AOP的事务配置(全自动)
1. xml配置(方法一)
1. <!--配置一个事务管理器-->
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager
">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!--配置事务属性,同时引入事务管理器-->
<tx:advice id="txAdvice" transaction-manager="txManager">
<tx:attributes>
<!--transfer。。。方法可读,-->
<tx:method name="transfer*" propagation="REQUIRED" isolation="REPEATABLE_READ"/>
<!-- 其它方法加可读写事务 -->
<tx:method name="*"/>
</tx:attributes>
</tx:advice>
<!-- 配置AOP:告诉spring框架哪些方法需要管理事务 -->
<aop:config>
<!-- 指定切入点 -->
<aop:advisor advice-ref="txAdvice" pointcut="execution(* com.rqy.service.*.*(..))"/>
</aop:config>
2. 注解事务(方法二)
1. 类里面加注解事务,就不用指明切入点了,默认在该类中加入该事务管理
2. xml需要声明自动开启事务注解驱动:<tx:annotation-driven transaction-manager="txManager"></tx:annotation-driven>
3. 注解直接加在方法上面
* @Transactional(propagation = Propagation.REQUIRED,isolation = Isolation.DEFAULT)
* @Transactional:直接写这个就置默认隔离级别和传播行为
纯javaConfig(全注解配置)
1. 类上面声明
//声明我是配置文件
@Configuration
//声明扫描范围
@ComponentScan(basePackages = "com.rqy")
//声明自动开启事务注解
@EnableTransactionManagement
//开启AspectJ注解
@EnableAspectJAutoProxy
2. 注解类
* //声明我是配置文件
@Configuration
//声明扫描范围
@ComponentScan(basePackages = "com.rqy")
//声明自动开启事务注解
@EnableTransactionManagement
//开启AspectJ注解
@EnableAspectJAutoProxy
public class SpringConfig {
//配置数据源
@Bean
public ComboPooledDataSource comboPooledDataSource() throws PropertyVetoException {
ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource();
comboPooledDataSource.setDriverClass("com.mysql.jdbc.Driver");
comboPooledDataSource.setJdbcUrl("jdbc:mysql://localhost:3306/spring_day04?serverTimezone=UTC");
comboPooledDataSource.setUser("root");
comboPooledDataSource.setPassword("123456");
return comboPooledDataSource;
}
//配置JdbcTemplate
@Bean
public JdbcTemplate jdbcTemplate(ComboPooledDataSource dataSource){
JdbcTemplate jdbcTemplate = new JdbcTemplate();
jdbcTemplate.setDataSource(dataSource);
return jdbcTemplate;
}
//配置事务管理器
@Bean
public DataSourceTransactionManager dataSourceTransactionManager(ComboPooledDataSource dataSource){
DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager();
dataSourceTransactionManager.setDataSource(dataSource);
return dataSourceTransactionManager;
}
}
3. 实例类
* @Component
public class AccountDaoImpl2 implements AccountDao {
@Autowired
JdbcTemplate jdbcTemplate;
public void out(String outer, Integer money) {
String sql = "update account set money=money-? where username=?";
jdbcTemplate.update(sql, money, outer);
}
public void inner(String inner, Integer money) {
String sql = "update account set money=money+? where username=?";
jdbcTemplate.update(sql, money, inner);
}
}
* @Transactional
@Component("accountService5")
public class AccountServiceImpl5 implements AccountService {
@Autowired
AccountDao accountDao;
public void transfer( String inner, String outer, Integer money) {
//第一个进账
accountDao.inner(inner,money);
//第二个出账
int i=10/0;
accountDao.out(outer,money);
}
}
4. 测试类
* @RunWith(SpringJUnit4ClassRunner.class)
//不加载配置文件的写法,如果有多个配置类,用,隔开。
@ContextConfiguration(classes = {SpringConfig.class})
public class ConfigTest {
//去找代理对象
@Autowired
@Qualifier("accountService5")
AccountService accountService;
@Test
public void test(){
accountService.transfer("rose","jack",2000);
}
}
传播行为
1. PROPAGATION_REQUIRED
required , 必须 【默认值】
* 支持当前事务,A如果有事务,B将使用该事务。
如果A没有事务,B将创建一个新的事务。
2. PROPAGATION_SUPPORTS:supports ·
* 支持当前事务,A如果有事务,B将使用该事务。
如果A没有事务,B将以非事务执行。
3. PROPAGATION_REQUIRES_NEW:如果A有事务,将A的事务挂起,B创 建一个新的事务如果A没有事务,B创建一个新的事务
06-Spring03-事务管理的更多相关文章
- MySQL基础篇(06):事务管理,锁机制案例详解
本文源码:GitHub·点这里 || GitEE·点这里 一.锁概念简介 1.基础描述 锁机制核心功能是用来协调多个会话中多线程并发访问相同资源时,资源的占用问题.锁机制是一个非常大的模块,贯彻MyS ...
- 测试MySQL事务管理
1.MySQL 版本 mysql> select version(); +------------+ | version() | +------------+ -log | +--------- ...
- Spring事务管理5-----声明式事务管理(3)
声明式事务管理 基于注解 在配置文件中需要开启注解驱动<tx:annotation-driven transaction-manager="transactionManager&qu ...
- Spring05——Spring 如何实现事务管理
在此之前,我们已经了解了 Spring 相关的基础知识,今天将为给位带来,有关 Spring 事务代理的相关知识.关注我的公众号「Java面典」,每天 10:24 和你一起了解更多 Java 相关知识 ...
- SpringBoot2 整合JTA组件,多数据源事务管理
本文源码:GitHub·点这里 || GitEE·点这里 一.JTA组件简介 1.JTA基本概念 JTA即Java-Transaction-API,JTA允许应用程序执行分布式事务处理,即在两个或多个 ...
- Spring基于AOP的事务管理
Spring基于AOP的事务管理 事务 事务是一系列动作,这一系列动作综合在一起组成一个完整的工作单元,如果有任何一个动作执行失败,那么事务 ...
- spring声明式事务管理总结
事务配置 首先在/WEB-INF/applicationContext.xml添加以下内容: <!-- 配置事务管理器 --> <bean id="transactionM ...
- SpringMVC+MyBatis整合——事务管理
项目一直没有做事务管理,这几天一直在想着解决这事,今天早上终于解决了.接下来直接上配置步骤. 我们项目采用的基本搭建环境:SpringMVC.MyBatis.Oracle11g.WebLogic10. ...
- Spring Boot中的事务管理
原文 http://blog.didispace.com/springboottransactional/ 什么是事务? 我们在开发企业应用时,对于业务人员的一个操作实际是对数据读写的多步操作的结合 ...
- 【Java EE 学习 54】【OA项目第一天】【SSH事务管理不能回滚问题解决】【struts2流程回顾】
一.SSH整合之后事务问题和总结 1.引入问题:DAO层测试 假设将User对象设置为懒加载模式,在dao层使用load方法. 注意,注释不要放开. 使用如下的代码块进行测试: 会报错:no sess ...
随机推荐
- C语言之函数用法总结
C语言函数概述: 构成C语言程序的基本模块,模块化编程的最小单位. 函数调用的基本方式: 函数调用时的数据传递: 函数调用的过程: 函数原型与函数定义的区别: 函数封装: 1.外界对函数的影响仅限于入 ...
- 案例分析丨H&M用设计冲刺将App研发周期缩短为6个月
案例背景 H&M是一家来自瑞典的时装公司,1947年成立.截至2018年6月,H&M 分店遍布全球 68 个国家和地区,分店数目为 4338 间. 作为快速服装生产商,H&M的 ...
- 【UEFI】---关于BIOS,EIST和PState&CState和CPU主频变化得关系
Intel处理器都支持Turbo和EIST,且一般情况下,各家厂商在BIOS中都会设置EIST和PState的开关,那么这些开关与CPU的频率的关系是什么呢?今天对此做个总结: 按照国际惯例,本次梳理 ...
- java 支持分词的高性能拼音转换工具,速度是 pinyin4j 的两倍
pinyin pinyin 是 java 实现的高性能中文拼音转换工具. 变更日志 创作目的 想为 java 设计一款便捷易用的拼音工具. 如何为 java 设计一款高性能的拼音转换工具 pinyin ...
- crawler 听课笔记 碎碎念 3 关于python的细枝末节的回顾复习
和廖雪峰大神的教程学了几遍后,还是出现了许多不足,于是就做一些回顾,列出一些python的细节问题,有一些就提一下,如果发现不清楚的话 还请移步https://www.liaoxuefeng.com/ ...
- pymysql 增
1.重点:数据库插入数据需要进行---------事物提交 其它:事物回滚 import pymysql # 注册用户 print("=========注册用户===========&quo ...
- es7中数组如何判断元素是否存在
const arr = [1,2,3,4,5,6] console.log(arr.includes(4)) //true
- .net core ef动态orderby
前言 最近在给大家写一套开源的.net core权限管理框架.现在已经写到前台UI + 后台动态查询的部分. 发现需要动态orderby但是网上没有现成的例子 二话不说上代码 建议namespace ...
- Python Selenium定位元素常用解决办法
在做web应用的自动化测试时,定位元素是必不可少的,这个过程经常会碰到定位不到元素的情况(报selenium.common.exceptions.NoSuchElementException), ...
- python + selenium定位页面元素的办法
1.什么是Selenium,为什么web测试,大家都用它? Selenium设计初衷就是为web项目的验收测试再开发.内核使用的是javaScript语言编写,几乎支持所以能运行javaScript的 ...