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 ...
随机推荐
- [UVA1494] Qin Shi Huang's National Road System
题目 戳这里 题解 从今天起我要改邪归正,好好刷题准备联赛! 这是一道经典的最小生成树题目. 枚举每一条边作为道士要修的路,求出包含这条边的最小生成树. 先求出原图的最小生成树. 如果要删的边在最小生 ...
- 关于C++读入数字按位取出与进制转换问题
这一片博客我就不写具体的一个题了,只是总结一种典型问题——读入数字按位取出. 就拿数字12345举例吧. 是首先,我们要取出个位.这样取出: 12345/1=12345 12345%10=5. ...
- python接口自动化测试 - unittest框架suite、runner详细使用
test suite 测试套件,理解成测试用例集 一系列的测试用例,或测试套件,理解成测试用例的集合和测试套件的集合 当运行测试套件时,则运行里面添加的所有测试用例 test runner 测试运行器 ...
- 个人任务day5
今日计划: 写登录界面,学习如何使用js做出界面跳转的进度条动态显示. 昨日成果: 创建用户数据库.
- 用Python实现根据角4点进行矩阵二维插值并画出伪彩色图
哈哈,题目取得这么绕,其实就是自己写了一个很渣的类似图像放大的算法.已知矩阵四周的4点,扩展成更大的矩阵,中间的元素值均匀插入,例如: 矩阵: 1 2 3 4 扩展成3x3的: 1 1.5 2 ...
- JavaWeb高级编程(上)
好久没更新了,发一篇以前记录学习的笔记. 面向读者:已经具有丰富的Java语言和Java SE平台知识的软件开发者和软件工程师. 预掌握知识: Internet.TCP.HTTP协议 HTML(5) ...
- Java练习题1
题目1: 编程实现,现在有如下的一个数组: int oldArr[] = {1,3,4,5,0,0,6,6,0,5,4,7,6,7,0,5}; 要求将以上数组中值为0的项去掉,将不为0的值存入一个新的 ...
- SpringBoot + Mybatis 和ssm 使用数据库的区别
积少成多 ---- 仅以此致敬和我一样在慢慢前进的人儿 相关内容: https://www.cnblogs.com/h-c-g/p/10252121.html 引 言 接触SpringBoot 后, ...
- 通过 SCF Component 轻松构建 REST API,再也不用熬夜加班了
本教程将分享如何通过 Serverless SCF Component .云函数 SCF 及 API 网关组件,快速构建一个 REST API 并实现 GET/PUT 操作. 当一个应用需要对第三方提 ...
- Mavn 项目 引入第三方jar包 导致ClassNotFoundException
案例 我有一个Maven构建的项目,项目模块之间有依赖关系,我需要用到一个本地的jar包,而该jar包不能通过配置pom.xml文件从远程仓库自动下载,于是我直接导入该jar包到其中一个项目,不通过p ...