Spring之深入理解声明式事务

何为事务?

事务就是把一系列的动作当成一个独立的工作单元,这些动作要么全部完成,要么全部不起作用。

事务的四个属性

1、原子性(atomicity)

事务是原子性操作,由一系列动作组成,事务的原子性确保动作要么全部完成,要么完全不起作用

2、一致性(consistency)

一旦所有事务动作完成,事务就要被提交。数据和资源处于一种满足业务规则的一致性状态中

3、隔离性(isolation)

可能多个事务会同时处理相同的数据,因此每个事务都应该与其他事务隔离开来,防止数据损坏

4、持久性(durability)

事务一旦完成,无论系统发生什么错误,结果都不会受到影响。通常情况下,事务的结果被写到持久化存储器中

Spring中的事务管理

Spring在不同的事务管理API之上定义了一个抽象层,使得开发人员不必了解底层的事务管理API就可以使用Spring的事务管理机制。Spring支持编程式事务管理和声明式的事务管理。

编程式事务管理

将事务管理代码嵌到业务方法中来控制事务的提交和回滚

缺点:必须在每个事务操作业务逻辑中包含额外的事务管理代码

声明式事务管理

将事务管理代码从业务方法中分离出来,以声明的方式来实现事务管理。将事务管理作为横切关注点,通过AOP方法模块化。Spring中通过Spring AOP框架支持声明式事务管理。

传播行为

REQUIRED 如果有事务在运行,当前的方法就在这个事务内运行,否则就开启一个新的事务,并在自己的事务内运行,默认传播行为
REQUIRED_NEW 当前方法必须启动新事务,并在自己的事务内运行,如果有事务正在运行,则将它挂起
SUPPORTS 如果有事务在运行,当前的方法就在这个事务内运行,否则可以不运行在事务中
NOT_SUPPORTED 表示该方法不应该运行在事务中。如果存在当前事务,在该方法运行期间,当前事务将被挂起。如果使用JTATransactionManager的话,则需要访问TransactionManager
MANDATORY 当前的方法必须运行在事务内部,如果没有正在运行的事务,就会抛出异常
NEVER 当前方法不应该运行在事务中,如果有运行的事务,就抛出异常
NESTED 如果有事务在运行,当前的方法就应该在这个事务的嵌套事务内运行。嵌套的事务可以独立于当前事务进行单独地提交或回滚。如果当前事务不存在,那么其行为与PROPAGATION_REQUIRED一样。

示例:基于注解的声明式事务管理

创建配置类:

@Configuration
//开启事务支持
@EnableTransactionManagement
@ComponentScan("com.zl.springBase.tx")
public class TxConfig {
@Bean
public DataSource dataSource() throws PropertyVetoException {
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setDriverClass("com.mysql.jdbc.Driver");
dataSource.setJdbcUrl("jdbc:mysql:///test");
dataSource.setUser("root");
dataSource.setPassword("root");
return dataSource;
} @Bean
public JdbcTemplate jdbcTemplate() throws PropertyVetoException {
return new JdbcTemplate(dataSource());
} //将事务管理器注入到容器中
@Bean
public PlatformTransactionManager transactionManager() throws PropertyVetoException {
return new DataSourceTransactionManager(dataSource());
}
}

持久层

@Repository
public class UserDao {
@Autowired
public JdbcTemplate jdbcTemplate; public void insertUser(){
String sql = "insert into user values(?,?)";
jdbcTemplate.update(sql,"admin",18);
}
}

业务层

@Service
public class UserService {
@Autowired
public UserDao userDao; @Transactional
public void insertUser(){
userDao.insertUser();
int a = 1/0;
}
}

测试结果:如果业务层方法没有加@Transactional注解,则即使发生1/0的错误,事务也不会回滚,数据还是会被添加到数据库中。加上@Transactional注解后发生错误,事务就回滚了。

声明式事务原理分析

  1. @EnableTransactionManagement利用TransactionManagementConfigurationSelector给容器中导入了两个组件

    • AutoProxyRegistrar
    • ProxyTransactionManagementConfiguration
  2. AutoProxyRegistrar做了什么?
    • 给容器中注册了一个InfrastructureAdvisorAutoProxyCreator组件
    • 这个组件利用后置处理器机制在对象创建以后,包装对象,返回一个代理对象。当代理对象执行目标方法,方法拦截器就会执行拦截。
  3. ProxyTransactionManagementConfiguration做了什么?
    • 给容器中注册事务增强器

      • 事务增强器要用到事务注解的信息,来解析事务
      • 还要用到TransactionInterceptor事务拦截器(保存了事务属性信息,和事务管理器),它是一个MethodInterceptor。
      • 在目标方法执行时,事务拦截器先获取事务相关属性,该获取事务管理器,然后执行目标方法,有异常,利用事务管理回滚操作;正常则提交事务。

八、Spring之深入理解声明式事务的更多相关文章

  1. spring boot中的声明式事务管理及编程式事务管理

    这几天在做一个功能,具体的情况是这样的: 项目中原有的几个功能模块中有数据上报的功能,现在需要在这几个功能模块的上报之后生成一条消息记录,然后入库,在写个接口供前台来拉取消息记录. 看到这个需求,首先 ...

  2. spring基于xml的声明式事务控制配置步骤

    <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.sp ...

  3. spring学习08(声明式事务)

    11.声明式事务 11.1 回顾事务 事务在项目开发过程非常重要,涉及到数据的一致性的问题,不容马虎! 事务管理是企业级应用程序开发中必备技术,用来确保数据的完整性和一致性. 事务就是把一系列的动作当 ...

  4. Spring学习笔记3—声明式事务

    1 理解事务 事务:在软件开发领域,全有或全无的操作被称为事务.事务允许我们将几个操作组合成一个要么全部发生要么全部不发生的工作单元. 事务的特性: 原子性:事务是由一个或多个活动所组成的一个工作单元 ...

  5. spring事物配置,声明式事务管理和基于@Transactional注解的使用

    http://blog.csdn.net/bao19901210/article/details/41724355 http://www.cnblogs.com/leiOOlei/p/3725911. ...

  6. Spring第13篇—–Spring整合Hibernate之声明式事务管理

    不容置疑的我们可以知道Spring的事务管理是通过AOP(AOP把我们的事务管理织入到我们的业务逻辑里面了)的方式来实现的,因为事务方面的代码与spring的绑定并以一种样板式结构使用.(面向切面编程 ...

  7. spring基于XML的声明式事务控制

    <?xml version="1.0" encoding="utf-8" ?><beans xmlns="http://www.sp ...

  8. Spring学习笔记:声明式事务管理增删改查业务

    一.关于是事务 以方法为单位,进行事务控制:抛出异常,事务回滚. 最小的执行单位为方法.决定执行成败是通过是否抛出异常来判断的,抛出异常即执行失败 二.声明式事务: 声明式事务(declarative ...

  9. spring学习笔记(22)声明式事务配置,readOnly无效写无异常

    在上一节内容中.我们使用了编程式方法来配置事务,这种优点是我们对每一个方法的控制性非常强.比方我须要用到什么事务,在什么位置假设出现异常须要回滚等.能够进行非常细粒度的配置.但在实际开发中.我们可能并 ...

随机推荐

  1. C语言--计算程序执行时间

    C语言–计算程序执行时间1. gettimeofday精度1us #include<stdio.h>#include<sys/time.h> int main(){ /* 定义 ...

  2. C++ day01-C++的函数和对象

    C++的函数和对象 1.1 1 混合型语言 c++以.cpp为文件扩展名,有且只有一个名为main的主函数,因保留了这个面向过程的主函数,所以被称为混合语言 2 注释方式 . C++的注释方式有两种, ...

  3. hive引擎的选择:tez和spark

    背景 mr引擎在hive 2中将被弃用.官方推荐使用tez或spark等引擎. 选择 tez 使用有向无环图.内存式计算. spark 可以同时作为批式和流式的处理引擎,减少学习成本. 问题& ...

  4. Java入门系列之字符串创建方式、判断相等(一)

    前言 陆续从0开始学习Java出于多掌握一门语言以后的路也会更宽,.NET和Java兼顾,虽然路还很艰难,但事在人为.由于Java和C#语法相似,所以关于一些很基础的内容不会再重头讲,Java系列中所 ...

  5. Redis for OPS 04:主从复制

    写在前面的话 Redis 的主从其实和 MySQL 类似,更多的还是作为备份的功能存在,在复杂的 Rediis 集群架构中,主从也是不可或缺的. 主从复制 主从复制原理: 1. 从库通过命令连接到主库 ...

  6. GO 键盘输入和打印输出

    键盘输入和打印输出 一.打印输出 1.1 fmt包 fmt包实现了类似C语言printf和scanf的格式化I/O.格式化verb('verb')源自C语言但更简单. 详见官网fmt的API:http ...

  7. C#比较两个对象中的指定字段值是否相等

    一.创建CompareFieldAttribute标识要比较的字段 using System; namespace CompareObjField { /// <summary> /// ...

  8. MySQL学习——操作视图

    MySQL学习——操作视图 摘要:本文主要学习了使用DDL语句操作视图的方法. 了解视图 是什么 视图是从一个.多个表或者视图中导出的表,包含一系列带有名称的数据列和若干条数据行. 特点 视图不是数据 ...

  9. Python【day 15-2】基本数据类型-dict tuple set

    '''''' ''' 变量的数据类型 int str bool list 5.字典 dict 定义和写法:由{}表示,每个元素是key:value的键值对形式,元素间是逗号隔开 特点: 1.key是可 ...

  10. [转]Outlook API

    本文转自:https://www.cnblogs.com/yl153/p/6711519.html 1.Outlook简介 若要从Outlook 外控制Outlook对象,必须在编写代码的工程中建立对 ...