一、spring的事务管理

1、引出事务的经典例子:银行转账发生异常

✿ 解决:把转出钱和转入钱的业务放到同一个事务空间。

■ 分析转账过程流程:

① 首先,获取 DataSource 对象;
② 其次,获取 DataSource 中的 Connection 对象;
③ 接着,设置取消事务的自动提交方式: connection.setAutoCommit(false);
④ 然后,把 connection 绑定到当前线程中;
从当前线程中获取 Connection 对象
⑥ 如果正常执行,则提交事务:提交事务:connection.commit(); 如果出现异常,则回滚事务:回滚事务:connection.rollback();

2、Spring 的事务管理主要包括 3 个:PlatformTransactionManager、TransactionDefinition、TransactionStatus

  • PlatformTransactionManager:根据 TransactionDefinition 提供的事务属性配置信息,创建事务

  • TransactionDefinition:封装事务的隔离级别和超时时间,是否为只读事务和事务的隔离级别和传播规则等事务属性.

  • TransactionStatus: 封装了事务的具体运行状态。如是否是新开启事务,是否已经提交事务,设置当前事务为rollback-only.

■ PlatformTransactionManager

✿ 记:常用的事务管理器:

  • JDBC/MyBatis:DataSourceTransactionManager
  • Hibernate: HibernateTransactionManager

3、事务传播规则 TransactionDefinition

(1)事务的传播规则(传播行为):

在一个事务方法中,调用了其他事务的方法,此时事务该如何传递,按照什么规则传播.

(2)传播规则适应的情况:

■ 情况一:需要尊重/遵从当前事务

  • REQUIRED:(常用)必须存在一个事务,如果当前存在一个事务,则加入到该事务中,否则,新建一个事务.

  • SUPPORTS:支持当前事务,如果当前存在事务,则使用该事务,否则,以非事务形式运行.

  • MANDATORY:必须要存在事务,如果当存在事务,就使用该事务,否则,非法的事务状态异常:(IllegalTranactionStatusException)

■ 情况二:不遵从当前事务的

  • REQUIRES_NEW:(常用)不管当前是否存在事务,都会新开启一个事务.必须是一个新的事务.
  • NOT_SUPPORTED:以非事务方式执行,如果当前存在事务,把当前事务挂起(暂停).
  • NEVER:不支持事务,如果当前存在事务,抛出一个异常.

■ 情况三:寄生事务(外部事务/内部事务/嵌套事务)

  • NESTED:寄生事务,如果当前存在事务,则在内部事务内执行.如果当前不存在事务,则创建一个新的事务.

    寄生事务可以通过数据库savePoint(保存点)来实现,奇生事务可以回滚的,但是他的回滚不影响外部事务.但是外部事务的回滚会影响寄生事务.

    • 寄生事务并不是所有的事务管理器都支持,比如HibernateTransactionManager默认就不支持,需要手动去开启.
    • Jdbc和MyBatis的事务管理器:DataSourceTransactionManager:默认就是支持的.

二、事务配置

1、使用xml配置jdbc事务

	<!-- ===============好比是AOP,事务增强================================== -->
<!-- 1、what:配置jdbc事务管理器 -->
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean> <!-- 2:when:配置事务管理器增强(环绕增强) --><!-- 关联what -->
<tx:advice id="txAdvice" transaction-manager="txManager">
<tx:attributes>
<tx:method name="trans"/>
</tx:attributes>
</tx:advice> <!-- 3、where:配置切面 --><!-- 关联when -->
<aop:config>
<aop:pointcut id="txPc" expression="execution(* com.shan.service.*Service.*(..))" />
<aop:advisor advice-ref="txAdvice" pointcut-ref="txPc"/>
</aop:config>

2、事务增强的属性配置 <tx:method/> 元素的属性:

属性 必要? 默认 描述
name 匹配方法的模式
propagation 事务的传播规则 required
isolation 事务的隔离级别 default DEFAULT:使用数据库自身设置的隔离级别,其他四种都是Spring通过java代码模拟出来的
timeout 事务超时时间 -1 缺省 -1 表示使用底层数据库自身的超时时间
read-only 是否是只读事务 false 若对于查询方法,设置只读,会提高性能,例如Hibernate
rollback-for 遇到什么异常做回滚 java.lang.RuntimeException 当我们在业务方法中,抛出一个Runtime异常,则事务回滚。自定义异常,若是需要配置多个异常,使用,隔开
no-rollback-for 遇到什么异常不做回滚

3、使用注解配置jdbc事务

  • 注解:@Transactional

  • 注解属性:name、propagation、isolation、timeout、read-only、rollback-for、no-rollback-for

  • 注解第三方解析:

    <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource"></property>
    </bean>
    <!-- tx注解解析器 -->
    <tx:annotation-driven transaction-manager="txManager"/>

■ 注解@Transactional使用:

@Service@Transactional
public class AccountServiceImpl implements IAccountService{ @Autowired
private IAccountDAO dao; @Override
public void trans(Long outId, Long inId, int money) {
dao.transOut(outId, money);
int a = 1/0; //算术异常
dao.transIn(inId, money);
} //若是有查询方法,可以再贴注解@Transactional添加注解属性
@Transactional(readOnly = true)
public void listXX() { } }

4、Java Config 配置

@Configuration 配置

@import(配置子类)

@Bean 配置创建bean对象

@ComponentScan ioc注解解析器

@EnableTransactionManagement 事务注解解析器

■ DataSourceConfig.java

//当前项目的连接池的配置类
@Configuration
@PropertySource("classpath:db.properties")
public class DataSourceConfig {
@Value("${jdbc.driverClassName}")
private String driverClassName;
@Value("${jdbc.url}")
private String url;
@Value("${jdbc.username}")
private String username;
@Value("${jdbc.password}")
private String password;
@Value("${jdbc.initialSize}")
private int initialSize; //配置连接池的Bean
@Bean
public DataSource dataSource() {
DruidDataSource ds = new DruidDataSource();
ds.setDriverClassName(driverClassName);
ds.setUrl(url);
ds.setUsername(username);
ds.setPassword(password);
ds.setInitialSize(initialSize);
return ds;
}
}

■ AppConfig.java

//当前项目的配置类,好比是pplicationContext.xml
@Configuration //标识当前类为一个配置类
@Import(DataSourceConfig.class) //包含其他的配置类
@ComponentScan //ioc注解解析器【di注解解析器默认是导入的】
@EnableTransactionManagement//事务注解解析器
public class AppConfig { //创建事务管理的Bean
@Bean
public DataSourceTransactionManager txManager(DataSource ds) {
return new DataSourceTransactionManager(ds);
}
}

■ App.java

@SpringJUnitConfig(classes = AppConfig.class)
public class App { @Autowired
private IAccountService service; @Test
void testTrans() throws Exception {
service.trans(1L, 2L, 100);
}
}

学习Spring5必知必会(7)~Spring tx的更多相关文章

  1. [ 学习路线 ] 2015 前端(JS)工程师必知必会 (2)

    http://segmentfault.com/a/1190000002678515?utm_source=Weibo&utm_medium=shareLink&utm_campaig ...

  2. 《SQL必知必会》学习笔记二)

    <SQL必知必会>学习笔记(二) 咱们接着上一篇的内容继续.这一篇主要回顾子查询,联合查询,复制表这三类内容. 上一部分基本上都是简单的Select查询,即从单个数据库表中检索数据的单条语 ...

  3. 学习《SQL必知必会(第4版)》中文PDF+英文PDF+代码++福达BenForta(作者)

    不管是数据分析还是Web程序开发,都会接触到数据库,SQL语法简洁,使用方式灵活,功能强大,已经成为当今程序员不可或缺的技能. 推荐学习<SQL必知必会(第4版)>,内容丰富,文字简洁明快 ...

  4. 《MySQL必知必会》学习笔记——前言

    前言 MySQL已经成为世界上最受欢迎的数据库管理系统之一.无论是用在小型开发项目上,还是用来构建那些声名显赫的网站,MySQL都证明了自己是个稳定.可靠.快速.可信的系统,足以胜任任何数据存储业务的 ...

  5. 《SQL必知必会》学习笔记整理

    简介 本笔记目前已包含 <SQL必知必会>中的所有章节. 我在整理笔记时所考虑的是:在笔记记完后,当我需要查找某个知识点时,不需要到书中去找,只需查看笔记即可找到相关知识点.因此在整理笔记 ...

  6. 《SQL必知必会》学习笔记(一)

    这两天看了<SQL必知必会>第四版这本书,并照着书上做了不少实验,也对以前的概念有得新的认识,也发现以前自己有得地方理解错了.我采用的数据库是SQL Server2012.数据库中有一张比 ...

  7. mysql学习--mysql必知必会1

     例如以下为mysql必知必会第九章開始: 正則表達式用于匹配特殊的字符集合.mysql通过where子句对正則表達式提供初步的支持. keywordregexp用来表示后面跟的东西作为正則表達式 ...

  8. mysql学习--mysql必知必会

      上图为数据库操作分类:     下面的操作參考(mysql必知必会) 创建数据库 运行脚本建表: mysql> create database mytest; Query OK, 1 row ...

  9. 数据库学习之中的一个: 在 Oracle sql developer上执行SQL必知必会脚本

    1 首先在開始菜单中打开sql developer: 2. 创建数据库连接 点击左上角的加号 在弹出的对话框中填写username和password 測试假设成功则点击连接,记得角色要写SYSDBA ...

  10. SQL必知必会,带你系统学习

    你一定听说过大名鼎鼎的Oracle.MySQL.MongoDB等,这些数据库都是基于一个语言标准发展起来的,那就是SQL. SQL可以帮我们在日常工作中处理各种数据,如果你是程序员.产品经理或者是运营 ...

随机推荐

  1. 【记录一个问题】在goland中的_test.go文件中,点右键点run,无法执行测试用例

    比较奇怪的是: 在命令行下,用 test -v alloc_test.go -test.run TestAlloc_utilJoinCPUAndGpu alloc.go 可以执行测试用例 比较奇怪的是 ...

  2. k8s通过Service访问Pod

    如何创建服务 1.创建Deployment #启动三个pod,运行httpd镜像,label是run:mcw-httpd,Seveice将会根据这个label挑选PodapiVersion: apps ...

  3. kubernetes之部署traefik-ingress分为http和https

    1 理解Ingress 简单的说,ingress就是从kubernetes集群外访问集群的入口,将用户的URL请求转发到不同的service上.Ingress相当于nginx.apache等负载均衡方 ...

  4. 学习JAVAWEB第四天

    # 今日内容 1. JDBC基本概念 2. 快速入门 3. 对JDBC中各个接口和类详解 ## JDBC: 1. 概念:Java DataBase Connectivity Java 数据库连接, J ...

  5. 解决matplotlib中文不显示问题

    在导入库时添加如下几行代码 from pylab import mpl mpl.rcParams['font.sans-serif'] = ['FangSong'] # 指定默认字体 mpl.rcPa ...

  6. 第09讲:Flink 状态与容错

    Flink系列文章 第01讲:Flink 的应用场景和架构模型 第02讲:Flink 入门程序 WordCount 和 SQL 实现 第03讲:Flink 的编程模型与其他框架比较 第04讲:Flin ...

  7. Arduino+ESP32 之 驱动GC9A01圆形LCD(二),移植LVGL,跑示例程序,显示自制图片

    在前文Arduino+ESP32 之 驱动GC9A01圆形LCD(一), 我们已经移植好了arduino GFX库, 该库的示例程序内,还有LVGL的示例程序哦. arduino环境下移植lvgl是很 ...

  8. ApacheCN Kali Linux 译文集 20211020 更新

    Kali Linux 秘籍 中文版 第一章 安装和启动Kali 第二章 定制 Kali Linux 第三章 高级测试环境 第四章 信息收集 第五章 漏洞评估 第六章 漏洞利用 第七章 权限提升 第八章 ...

  9. JSP response.setCharacterEncoding与response.setContentType的区别

    问题描述 昨天在参考别人的项目时,发现页面引用js,css等文件总是乱码,后来才发现是MIME类型统一设置为text/html,并且仅仅编码设置了浏览器端的解析编码.另外,可以先通过文本编辑器(如no ...

  10. JS Map与Set

    笔记整理自:廖雪峰老师的JS教程 Map JavaScript的对象有个小问题,就是键必须是字符串.但实际上Number或者其他数据类型作为键也是非常合理的. 为了解决这个问题,最新的ES6规范引入了 ...