5.1 Spring事务管理概述

5.11 事务管理的核心接口

在Spring的所有jar包中,有一个名spring-tx-4.3.6RELEAS的jar包,是提供事务管理的依赖包。在该包的org.springframework.transaction包中,三个核心接口文件分别是PlatformTransactionManagerTransactionDefinitionTransactionStatus

1.PlatfromTransactionManager

PlatfromTransactionManager接口是Spring提供的平台事务管理器,主要用于管理事务。有3个事务操作的方法:

TransactionStatus getTransaction( TransactionDefinition definition ):用于获取事务状态信息

void commit( TransactionStatus status ):提交事务

void rollback( Transaction status ):回滚事务

PlatformTransactionManager接口只是代表事务管理的接口,并不知道底层是如何管理事务的,具体如何管理事务则由它的实现类来完成。该接口常见的几个实现类如下:

(1)、用于配置JDBC数据源的事务管理器:
org.springframework.jdbc.datasource.DataSourceTransactionManager
(2)、用于配置Hibernate的事务管理器:
org.springframework.orm.hibernate4.HibernateTransactionManager
(3)、用于配置全局事务管理器:
org.springframework.transaction.jta.JtaTransactionManager

当底层采用不同的持久层技术时,系统只需使用不同的实现类。

2.TransactionDefinition

事务定义(描述)的对象,该对象中定义了事务规则,并提供获取事务相关信息的方法,具体如下:

String getName():获取事务对象名称

int getlsolationLevel:获取事务的隔离级别

int getPropagationBehavior():获取事务的传播行为

int getTimeout():获取事务的超时时间

boolean isReadOnly():获取事务的是否只读

传播行为:指在同一个方法中,不同操作前后所使用的事务。传播行为有很多种:

传播行为可以控制是否需要创建事务以及如何创建事务,查询不影响数据的改变,不需要事务管理;插入、更新和删除需要事务管理。如果没有指定事务的传播行为,Spring默认传播行为是REQUIRED(required)

3.TransactionStatus

TransactionStatus接口是事务的状态,它描述了某一时间点上事务的状态信息,该接口有6个方法:

void flush():刷新事务

boolean hasSavepoint():获取是否存在保存点

boolean isCompleted():获取事务是否完成

boolean isNewTransaction():获取是否是新事物

boolean isRollbackOnly():获取是否回滚

void setRollbackOnly():设置事务回滚

5.12 事务管理的方式:

传统的编程式事务管理:通过编写代码实现的事务管理,包括定义事务的开始、正常执行后的事务提交和异常时的事务回滚

声明式事务管理:通过AOP技术实现的事务管理,主要思想是将事务管理作为一个“切面”代码单独编写,然后通过AOP技术将管理“切面”代码织入到业务目标类中。

5.2 声明式事务管理

5.21 基于XML方式的声明式事务

tx命名空间下提供了<tx:advice>元素来配置事务的通知(增强处理)。当使用<tx:advice>元素配置了事务的增强处理后,就可以通过编写AOP配置,让Spring自动对目标生成代理。

配置<tx:advice>元素时,通常需要指定id和transaction-manager属性。transaction-manager属性用于指定事务管理器。除此之外,还需要配置一个<tx:attributes>子元素,该子元素可以通过配置多个<tx:method>子元素来配置执行事务的细节。

转账方法编写:

        /**
* 转账
* inUser:收款人
* outUser:汇款人
* money:收款金额
*/
public void transfer(String outUser, String inUser, Double money) {
// 收款时,收款用户的余额=现有余额+所汇金额
this.jdbcTemplate.update("update account set balance = balance +? "
+ "where username = ?",money, inUser);
// 模拟系统运行时的突发性问题
int i = /;
// 汇款时,汇款用户的余额=现有余额-所汇金额
this.jdbcTemplate.update("update account set balance = balance-? "
+ "where username = ?",money, outUser);
}

XML文件:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.3.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.3.xsd"> <!-- 1.配置数据源 -->
<bean id="dataSource222"
class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <!--数据库驱动 -->
<property name="driverClassName" value="com.mysql.jdbc.Driver" /> <!--连接数据库的url -->
<property name="url" value="jdbc:mysql://localhost/spring" /> <!--连接数据库的用户名 -->
<property name="username" value="root" /> <!--连接数据库的密码 -->
<property name="password" value="****" />
</bean> <!-- 2.配置JDBC模板 -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <!-- 默认必须使用数据源 -->
<property name="dataSource" ref="dataSource222" /> </bean> <!--3.定义id为accountDao的Bean -->
<bean id="accountDao" class="com.itheima.jdbc.AccountDaoImpl"> <!-- 将jdbcTemplate注入到AccountDao实例中 -->
<property name="jdbcTemplate" ref="jdbcTemplate" />
</bean> <!-- 4.事务管理器,依赖于数据源 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource222" />
</bean> <!-- 5.编写通知:对事务进行增强(通知),需要编写对切入点和具体执行事务细节 -->
<tx:advice id="txAdvice123" transaction-manager="transactionManager">
<tx:attributes>
<!-- name:*表示任意方法名称,传播行为,隔离级别,是否只读-->
<tx:method name="*" propagation="REQUIRED" isolation="DEFAULT" read-only="false" />
</tx:attributes>
</tx:advice> <!-- 6.编写AOP,让spring自动对目标生成代理,需要使用AspectJ的表达式 -->
<aop:config>
<!-- 切入点 -->
<aop:pointcut expression="execution(* com.itheima.jdbc.*.*(..))"
id="txPointCut111" />
<!-- 切面:将切入点与通知整合 -->
<aop:advisor advice-ref="txAdvice123" pointcut-ref="txPointCut111" />
</aop:config>
</beans>

测试类:获取实例,调用方法,常规操作

@Test///基于XML方式的声明式事务
public void xmlTest(){
ApplicationContext applicationContext =
new ClassPathXmlApplicationContext("applicationContext.xml"); // 获取AccountDao实例
AccountDao accountDao =
(AccountDao)applicationContext.getBean("accountDao"); // 调用实例中的转账方法
accountDao.transfer("Jack", "Rose", 100.0); // 输出提示信息
System.out.println("转账成功!");
}

5.22 基于Annotation(注解)方式的声明式事务

两个套路

1.在Spring容器中注册事务注解驱动:

<tx:annotation-driven transaction-manager="transactionManager"/>

XML文件:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.3.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.3.xsd">
<!-- 1.配置数据源 -->
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <!--数据库驱动 -->
<property name="driverClassName" value="com.mysql.jdbc.Driver" /> <!--连接数据库的url -->
<property name="url" value="jdbc:mysql://localhost/spring" /> <!--连接数据库的用户名 -->
<property name="username" value="root" /> <!--连接数据库的密码 -->
<property name="password" value="17251104238" />
</bean> <!-- 2.配置JDBC模板 -->
<bean id="jdbcTemplate"
class="org.springframework.jdbc.core.JdbcTemplate"> <!-- 默认必须使用数据源 -->
<property name="dataSource" ref="dataSource" /> </bean> <!--3.定义id为accountDao的Bean -->
<bean id="accountDao" class="com.itheima.jdbc.AccountDaoImpl">
<!-- 将jdbcTemplate注入到AccountDao实例中 -->
<property name="jdbcTemplate" ref="jdbcTemplate" />
</bean> <!-- 4.事务管理器,依赖于数据源 -->
<bean id="transactionManager" class=
"org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean> <!-- 5.注册事务管理器驱动 -->
<tx:annotation-driven transaction-manager="transactionManager"/> </beans>

2.在方法transfer()前加注解:

@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, readOnly = false)

方法:

@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, readOnly = false)
public void transfer(String outUser, String inUser, Double money)
{
// 收款时,收款用户的余额=现有余额+所汇金额
this.jdbcTemplate.update("update account set balance = balance +? "
+ "where username = ?",money, inUser); // 模拟系统运行时的突发性问题
//int i = 1/0;
// 汇款时,汇款用户的余额=现有余额-所汇金额
this.jdbcTemplate.update("update account set balance = balance -? "
+ "where username = ?",money, outUser);
}

第5章 Spring的事务管理的更多相关文章

  1. 深入Spring:自定义事务管理

    转自: http://www.jianshu.com/p/5347a462b3a5 前言 上一篇文章讲了Spring的Aop,这里讲一下Spring的事务管理,Spring的事务管理是建立在Aop的基 ...

  2. Spring AOP事务管理(使用切面把事务管理起来)

    在<Spring Transaction 分析事务属性(事务的基本概念.配置)>基础上 http://blog.csdn.net/partner4java/article/details/ ...

  3. Spring的事务管理

    事务 事务:是逻辑上一组操作,要么全都成功,要么全都失败. 事务特性(ACID) 原子性:事务不可分割 一致性:事务执行的前后,数据完整性保持一致 隔离性:一个事务执行的时候,不应该受到其他事务的打扰 ...

  4. spring笔记--事务管理之声明式事务

    事务简介: 事务管理是企业级应用开发中必不可少的技术,主要用来确保数据的完整性和一致性, 事务:就是一系列动作,它们被当作一个独立的工作单元,这些动作要么全部完成,要么全部不起作用. Spring中使 ...

  5. Spring应用——事务管理

    事务基础:请参看:http://www.cnblogs.com/solverpeng/p/5720306.html 一.Spring 事务管理 1.前提:事务管理器 在使用 Spring 声明式事务管 ...

  6. spring+mybatis事务管理

    spring+mybatis事务管理 最近在和朋友做一个项目,考虑用springmvc+mybatis来做,之前在公司工作吧,对于数据库这块的配置也有人再弄,最近因为这个项目,我就上网学习了一些关于数 ...

  7. spring,mybatis事务管理配置与@Transactional注解使用[转]

    spring,mybatis事务管理配置与@Transactional注解使用[转] spring,mybatis事务管理配置与@Transactional注解使用 概述事务管理对于企业应用来说是至关 ...

  8. Spring高级事务管理难点剖析

    1Spring事务传播行为 所谓事务传播行为就是多个事务方法相互调用时,事务如何在这些方法间传播.Spring支持7种事务传播行为 PROPAGATION_REQUIRED(加入已有事务) 如果当前没 ...

  9. CSDN上看到的一篇有关Spring JDBC事务管理的文章(内容比较全) (转)

    JDBC事务管理 Spring提供编程式的事务管理(Programmatic transaction manage- ment)与声明式的事务管理(Declarative transaction ma ...

随机推荐

  1. Lua函数声明与调用

    lua编程中,我们经常也会遇到函数的声明定义和调用. [1]lua中函数定义与调用的方法 lua有两种函数定义和调用的方法(本质都是用属性,方式不同而已): (1)点号形式 (2)冒号形式 两种方法的 ...

  2. 『Broken Robot 后效性dp 高斯消元』

    Broken Robot Description 你作为礼物收到一个非常聪明的机器人走在矩形板上.不幸的是,你明白它已经破碎并且行为相当奇怪(随机).该板由N行和M列单元组成.机器人最初位于第i行和第 ...

  3. Linux学习笔记之grep命令和使用正则表达式

    0x00 正则表达式概述 正则表达式是描述一些字符串的模式,是由一些元字符和字符组成的字符串,而这些元字符是一些表示特殊意义的字符,即被正则表达式引擎表达的字符表示与其本意不同的一些字符. 0x01  ...

  4. JSON数据格式:以及XML文件格式,YML文件格式,properties文件格式

    JSON数据格式:以及XML文件格式,YML文件格式,properties文件格式   数据格式: json数据格式:属于轻量级数据格式,是javascript的一种描述数据的格式.具有易于解析,语法 ...

  5. prometheus消耗内存问题

    参考: https://stackoverflow.com/questions/56115912/why-does-prometheus-consume-so-much-memory https:// ...

  6. 2019 开创java面试笔试题 (含面试题解析)

      本人5年开发经验.18年年底开始跑路找工作,在互联网寒冬下成功拿到阿里巴巴.今日头条.开创等公司offer,岗位是Java后端开发,因为发展原因最终选择去了开创,入职一年时间了,也成为了面试官,之 ...

  7. 《CI/CD 流程以及原理说明》

    自动化部署 CI/CD 是一种通过在应用开发阶段引入自动化来频繁向客户交付应用的方法.CI/CD 的核心概念是持续集成.持续交付和持续部署.作为一个面向开发和运营团队的解决方案,CI/CD 主要针对在 ...

  8. iframe中操作主体页面的元素,方法

    在不使用三大框架的情况下,iframe的使用可以做到在页面中直接引入别的页面作为当前页面的一部分,但是在iframe的使用过程中存在一些相互之间的操作 例如在iframe中获取主页面的元素,使用主页面 ...

  9. Active Directory渗透测试典型案例

    0x01 前言 我有几个客户在渗透测试之前来找我,说他们的系统安全做得非常好,因为他们的漏洞扫描显示没有严重的漏洞并且已准备好进行安全测试,这使我在15分钟内利用AD中的错误配置获得了域管理员权限. ...

  10. linux rwx 权限说明

    Linux的文件和目录的权限,有RWX三种. r(Read,读取):对文件而言,具有读取文件内容的权限:对目录来说,具有浏览目录的权限. w(Write,写入):对文件而言,具有新增,修改,删除文件内 ...