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 ...
随机推荐
- Android通过子线程更新UI的几种方式
一般情况下,UI的更新都少不了Handler,首先我们先了解一下Handler机制: Handler消息机制 定义 Message 线程间通信的数据单元,可通过message携带需要的数据创建对象:M ...
- Frogger POJ - 2253(求两个石头之间”所有通路中最长边中“的最小边)
题意 题目主要说的是,有两只青蛙,在两个石头上,他们之间也有一些石头,一只青蛙要想到达另一只青蛙所在地方,必须跳在石头上.题目中给出了两只青蛙的初始位置,以及剩余石头的位置,问一只青蛙到达另一只青 ...
- <密码学系列>—信息安全威胁
懒惰等于将一个人活埋.--泰勒 本文已经收录至我的GitHub,欢迎大家踊跃star 和 issues. https://github.com/midou-tech/articles 点关注,不迷路! ...
- 3种基础的 REST 安全机制
安全是 RESTful web service 的基石,我们主要讨论以下3种主要的方法: Basic authentication Oauth 2.0 Oauth 2.0 + JWT 1. Basic ...
- spring boot 的 userRepository无法注入的问题
No qualifying bean of type 'xxx.xxx.xxx' available: expected at least 1 bean which qualifies as auto ...
- AVR单片机教程——UART进阶
本文隶属于AVR单片机教程系列. 在第一期中,我们已经开始使用UART来实现单片机开发板与计算机之间的通信,但只是简单地讲了讲一些概念和库函数的使用.在这一篇教程中,我们将从硬件与软件等各方面更深 ...
- 为BlueLake主题增加图片放大效果
fancyBox 是一个流行的媒体展示增强组件,可以方便为网站添加图片放大.相册浏览.视频弹出层播放等效果.优点有使用简单,支持高度自定义,兼顾触屏.响应式移动端特性,总之使用体验相当好. 现在,我们 ...
- idea怎么关闭项目
原文地址:https://jingyan.baidu.com/article/a3a3f8112169e78da2eb8a8d.html idea关闭项目可以按File-CloseProject按钮实 ...
- 创建dynamics CRM client-side (五) - 使用regular expression (正则表达式)来检查phone number
我们这次要使用account, 让我们首先重建一个JavaScript. 建议每个entity都创建专属的js // Converting functions to Namespace Notatio ...
- Nginx核心模块
error_log 语法:error_log file [ debug | info | notice | warn | error | crit ]默认值:${prefix}/logs/error. ...