今日知识

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-事务管理的更多相关文章

  1. MySQL基础篇(06):事务管理,锁机制案例详解

    本文源码:GitHub·点这里 || GitEE·点这里 一.锁概念简介 1.基础描述 锁机制核心功能是用来协调多个会话中多线程并发访问相同资源时,资源的占用问题.锁机制是一个非常大的模块,贯彻MyS ...

  2. 测试MySQL事务管理

    1.MySQL 版本 mysql> select version(); +------------+ | version() | +------------+ -log | +--------- ...

  3. Spring事务管理5-----声明式事务管理(3)

    声明式事务管理  基于注解 在配置文件中需要开启注解驱动<tx:annotation-driven transaction-manager="transactionManager&qu ...

  4. Spring05——Spring 如何实现事务管理

    在此之前,我们已经了解了 Spring 相关的基础知识,今天将为给位带来,有关 Spring 事务代理的相关知识.关注我的公众号「Java面典」,每天 10:24 和你一起了解更多 Java 相关知识 ...

  5. SpringBoot2 整合JTA组件,多数据源事务管理

    本文源码:GitHub·点这里 || GitEE·点这里 一.JTA组件简介 1.JTA基本概念 JTA即Java-Transaction-API,JTA允许应用程序执行分布式事务处理,即在两个或多个 ...

  6. Spring基于AOP的事务管理

                                  Spring基于AOP的事务管理 事务 事务是一系列动作,这一系列动作综合在一起组成一个完整的工作单元,如果有任何一个动作执行失败,那么事务 ...

  7. spring声明式事务管理总结

    事务配置 首先在/WEB-INF/applicationContext.xml添加以下内容: <!-- 配置事务管理器 --> <bean id="transactionM ...

  8. SpringMVC+MyBatis整合——事务管理

    项目一直没有做事务管理,这几天一直在想着解决这事,今天早上终于解决了.接下来直接上配置步骤. 我们项目采用的基本搭建环境:SpringMVC.MyBatis.Oracle11g.WebLogic10. ...

  9. Spring Boot中的事务管理

    原文  http://blog.didispace.com/springboottransactional/ 什么是事务? 我们在开发企业应用时,对于业务人员的一个操作实际是对数据读写的多步操作的结合 ...

  10. 【Java EE 学习 54】【OA项目第一天】【SSH事务管理不能回滚问题解决】【struts2流程回顾】

    一.SSH整合之后事务问题和总结 1.引入问题:DAO层测试 假设将User对象设置为懒加载模式,在dao层使用load方法. 注意,注释不要放开. 使用如下的代码块进行测试: 会报错:no sess ...

随机推荐

  1. 写了个 Task.WhenAll(t)的一个例子。

    public static void Main() { var t = Task.Run(() => { throw new Exception("aa"); }); Tas ...

  2. Ubuntu 19.10 安装 jupyter

    安装pip3 ubuntu 19.10 已经没有python了,取代的是python3. 执行sudo apt install python3-pip安装pip3 安装jupyter 执行sudo p ...

  3. 【C_Language】---一份程序看懂C程序printf()的几种常用用法

    闲来继续巩固我的学习之路,今天略微整理了一下,C程序中Printf()的一些常用用法,虽然自己以前好像会,但是不够系统,今天大致整理了一些,先贴上来看看,以后在看到其他,继续补充,希望能帮到一些像我一 ...

  4. java反序列化php序列化的对象

    最近工作中遇到一个需要解析php序列化后存入DB的array, a:4:{i:0;a:2:{s:11:"province";s:8:"0016";s:7:&qu ...

  5. pycharm 连接mysql失败

    1.下载与之对应的驱动 2.更改数据库的时区(问题大多数出现在这里) .查看时区 show variables like '%time_zone%'; .设置时区 set global time_zo ...

  6. ajxa的TypeError: $.ajax is not a function的冲突问题

    在加载onclick的方法异步过程中,浏览器报错 首先自我检查 原因一:没有加载Jquery库,原因二:$.ajax没有在$(function(){$.ajax();})中. 发现都不是 原因三:有没 ...

  7. ubuntu系统下载后的.deb软件安装命令

    查看某个软件是否安装,比如查看QQ软件是否安装并列出软件包名: dpkg -l | grep qq 删除某款软件:sudo dpkg -r 软件包名 安装软件 : sudo dpkg -i *.deb

  8. 9、python判断语句与循环语句

    前言:本文主要介绍python判断语句与循环语句,包括if语句.while循环.for循环.range函数. 一.if语句  关键字:if.elif.else,写法如下: # if if 条件: # ...

  9. Nginx code 状态码说明

    最近了解下Nginx的Code状态码,在此简单总结下. 先来再回顾一下一个http请求处理流程: 一个普通的http请求处理流程,如上图所示: A -> client端发起请求给nginx B ...

  10. Shell常用命令之curl

    curl命令 在Linux中curl是一个利用URL规则在命令行下工作的文件传输工具,可以说是一款很强大的http命令行工具.它支持文件的上传和下载,是综合传输工具,但按传统,习惯称url为下载工具. ...