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. tensorflow slim代码使用

    此处纯粹作为个人学习使用,原文连接:https://www.jianshu.com/p/dc24e54aec81 这篇文章是借鉴很多博文的,作为一个关于slim库的总结 导入slim模块 import ...

  2. Java 实现 HtmlEmail 邮件发送功能

    引言 在平常的企业级应用开发过程中,可能会涉及到一些资讯通知需要传达,以及软件使用过程中有一些安全性的东西需要及早知道和了解,这时候在局域网之间就可以通过发送邮件的方式了.以下就是代码实现了: pac ...

  3. php使用inotify扩展监控文件或目录的变化

    一.安装inotify扩展 1.下载inotify扩展源码 https://pecl.php.net/package/inotify 对于php7以上版本,请下载 inotify-2.0.0.tgz. ...

  4. NumPy 学习 第四篇:数组的基本操作

    在数组中,用axis(轴)表示维度,对于三维数组,axis参数的取值通常有: 当axis=None时,表示把数组展开为一维数组: 当axis=0时,表示按照行(第一维)进行计算: 当axis=1时,表 ...

  5. 用.net core实现反向代理中间件

    最近在将一些项目的rest api迁移到.net core中,最开始是用的Nginx做反向代理,将已经完成切换的部分切入系统,如下图所示: 由于迁移过程中也在进行代码重构,需要经常比较频繁的测试,以保 ...

  6. Python笔记:设计模式之命令模式

    命令模式,正如模式的名字一样,该模式中的不同操作都可以当做不同的命令来执行,可以使用队列来执行一系列的命令,也可以单独执行某个命令.该模式重点是将不同的操作封装为不同的命令对象,将操作的调用者与执行者 ...

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

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

  8. C#中在定义事件委托时怎样跨窗体传递参数

    场景 C#中委托与事件的使用-以Winform中跨窗体传值为例: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/100150700 ...

  9. 史上最全Winform中使用ZedGraph教程与资源汇总整理(附资源下载)

    场景 C#窗体应用中使用ZedGraph曲线插件绘制图表: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/99716066 Win ...

  10. GBT22239-2019等保2.0三级要求

    1 第三级安全要求 1.1 安全通用要求 1.1.1 安全物理环境 1.1.1.1 物理位置选择 本项要求包括: a) 机房场地应选择在具有防震.防风和防雨等能力的建筑内: b) 机房场地应避免设在建 ...