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. 基于appium的常用元素定位方法

    一.元素定位工具 app应用的元素使用的是控件定位,不同于web网页,web网页定位元素通常使用的是F12工具,那么在app当中我们则要借助其它的工具来辅助定位. 1.uiautomatorviewe ...

  2. RaiseException函数逆向

    书中内容: 代码逆向: 存在一个疑问:为什么在ExceptionAddress本来是错误产生代码的地址,但这里给存入一个_RaiseException的偏移地址. 答案在下个函数中:rtlRaiseE ...

  3. .Net Core技术研究-WebApi迁移ASP.NET Core2.0

    随着ASP.NET Core 2.0发布之后,原先运行在Windows IIS中的ASP.NET WebApi站点,就可以跨平台运行在Linux中.我们有必要先说一下ASP.NET Core. ASP ...

  4. Nginx反向代理Tomcat静态资源无法加载以及请求链接错误

     在使用Nginx实现Tomcat的负载均衡的时候,项目发布到了Tomcat,Nginx也配置好了, 当访问的时候发现了与预期不符 表现为: 静态资源加载失败 链接跳转地址错误 下面是我错误的配置文件 ...

  5. Java生鲜电商平台-SpringCloud微服务架构中网络请求性能优化与源码解析

    Java生鲜电商平台-SpringCloud微服务架构中网络请求性能优化与源码解析 说明:Java生鲜电商平台中,由于服务进行了拆分,很多的业务服务导致了请求的网络延迟与性能消耗,对应的这些问题,我们 ...

  6. python 通过使用pandas的实现的Excel的批量转换CSV文件的处理

    ---恢复内容开始--- 最近同事在处理文件导入的时候需要把一批文件换成CSV的格式,但是直觉修改后缀是不生效的,而且xlsx和xls的文件没法直接换成CVS的文件,所以找了一下方式,并且自己实现了p ...

  7. 禁止ViewPager滑动

    实现如下: public class NoScrollViewPager extends ViewPager { public NoScrollViewPager (Context context) ...

  8. WindowServer优化

    Windows Server 2016 禁止自动更新 1. 打开cmd,输入sconfig,出现如下图: 2. 输入5回车,在输入m回车,完成关闭自动更新.

  9. springboot + shiro + mysql + mybatis 工程快速搭建

    1. 新建 springboot 工程 2. 随便起个名字 3. 初始化工程 4. 导入 shiro 和 thymeleaf 依赖 <!-- thymeleaf依赖 --> <dep ...

  10. Matplotlib 日期格式转换

    官网链接:https://matplotlib.org/api/dates_api.html#matplotlib.dates.date2num import numpy as np import d ...