iis服务器助手广告广告
返回顶部
首页 > 资讯 > 精选 >Spring七大事务传递机制的实现原理是什么
  • 361
分享到

Spring七大事务传递机制的实现原理是什么

2023-07-05 16:07:04 361人浏览 安东尼
摘要

这篇“spring七大事务传递机制的实现原理是什么”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Spring七大事务传递机制

这篇“spring七大事务传递机制的实现原理是什么”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Spring七大事务传递机制的实现原理是什么”文章吧。

Spring事务传递机制原理

首先,我们通过org.springframework.transaction.annotation.Propagation来了解一下spring事务的传播定义:

REQUIRED(默认):

Support a current transaction, create a new one if none exists.

支持当前事务,如果没有则创建一个新的

SUPPORTS

Support a current transaction, execute non-transactionally if none exists.

支持当前事务,如果没有则不使用事务

MANDATORY

Support a current transaction, throw an exception if none exists

支持当前事务,如果没有事务则报错

REQUIRED_NEW

Create a new transaction, and suspend the current transaction if one exists.

新建一个事务,同时将当前事务挂起

NOT_SUPPORTED

Execute non-transactionally, suspend the current transaction if one exists

以无事务的方式执行,如果当前有事务则将其挂起

NEVER

Execute non-transactionally, throw an exception if a transaction exists.

以无事务的方式执行,如果当前有事务则报错

NESTED

Execute within a nested transaction if a current transaction exists,behave like PROPAGATION_REQUIRED else

如果当前有事务,则在当前事务内部嵌套一个事务,内部事务的回滚不影响当前事务。如果当前没有事务,就相当于REQUIRED

Note: Actual creation of a nested transaction will only work on specific transaction managers. Out of the box, this only applies to

the JDBC DataSourceTransactionManager when working on a JDBC 3.0 driver.

Some JTA providers might support nested transactions as well.

注意:该定义只能在JDBC3.0驱动下的DataSourceTransactionManager事务管理器中使用,有些JTA事务可能也会支持

接下来我们通过代码验证一下spring事务的传递性,在UserServiceImpl类添加两个方法如下:

@Transactional(propagation = Propagation.NEVER)public User findById(Long id) {    User user =  userMapper.findById(id);    System.out.println("find user:"+user);    return user;}@Transactionalpublic void transactionTest(int t) {    findById(t+0L);}

我们调用transactionTest方法,transactionTest没有配置Propagation,所以默认是REQUIRED,会在当前新建一个事务。transactionTest内部调用findById,由于findById事务传播定义为NEVER,表明它当前不能有事务,按理说这里会抛出异常,但是我们利用junit执行后发现,transactionTest是可以正常执行的。

事实上,如果使用@Transaction方法里嵌套调用的是同一个类的方法,spring代理会忽略嵌套方法的@Transaction配置。但是,如果是其他注入对象的方法,那么@Transaction配置就会生效。我们将上面的transactionTest方法的事务传播定义为NERVER,并新增一个insert操作,即使insert启用了事务并且抛出异常,但是事务不会生效,也不会有回滚的说法,程序会抛出异常但是数据会保存到数据库中:

@Transactional(propagation = Propagation.NEVER)public void transactionTest(int t) {    findById(t+0L);    insertUser("huangxl","abc123");}@Transactionalpublic int insertUser(String name, String passWord) {    User user = new User();    user.setPassword(password);    user.setUsername(name);    int insertCount =  userMapper.insertEntity(user);    if(insertCount == 1 ){        throw new RuntimeException("test transaction roll back");    }    return insertCount;}

接下来我们来测试不同类之间的方法(事务)调用,以下的测试都是基于junit执行TransactionTestServiceImpl.test()方法

一、Propagation.NERVER的测试

下面我们将UserService注入到TransactionTestServiceImpl中,test方法使用@Transactional,UserService findById事务传播定义不变,还是NERVER。

UserserviceImpl:@Servicepublic class TransactionTestServiceImpl implements TransactionTestService {    @Autowired    private UserService userService;    @Override    @Transactional    public void test() {        userService.findById(1L);    }}TransactionTestServiceImpl:@Servicepublic class UserServiceImpl implements UserService {    @Override    @Transactional(propagation = Propagation.NEVER)    public User findById(Long id) {        User user =  userMapper.findById(id);        System.out.println("find user:"+user);        return user;    }}

由于test默认启用了事务,findById不允许当前有事务,所以我们执行test方法后会发现程序抛出了异常:

org.springframework.transaction.IllegalTransactionStateException: Existing transaction found for transaction marked with propagation ‘never’

结论:

NERVER 不允许当前存在事务

二、Propagation.REQUIRED的测试

UserserviceImpl:@Transactionalpublic int insertUser(String name, String password) {    User user = new User();    user.setPassword(password);    user.setUsername(name);    int insertCount =  userMapper.insertEntity(user);    if(insertCount == 1 ){        throw new RuntimeException("test transaction roll back");    }    return insertCount;}TransactionTestServiceImpl:@Transactionalpublic void test() {    try {        userService.insertUser("abc", "123");    } catch (Exception e) {        //do Nothing    }    userMapper.updateUserPassWord(1L, "456");}

我们会发现,即使捕获了userService.insertUser抛出的异常,test还是把insertUser和updateUserPassword操作当成是一个整体,整个事务还是回滚了,程序抛出了下面的异常:

org.springframework.transaction.UnexpectedRollbackException: Transaction rolled back because it has been marked as rollback-only

结论:

REQUIRED子事务会影响当前事务的提交、回滚

三、Propagation.NESTED的测试

UserserviceImpl:@Transactional(propagation = Propagation.NESTED)public int insertUser(String name, String password) {    User user = new User();    user.setPassword(password);    user.setUsername(name);    int insertCount =  userMapper.insertEntity(user);    if(insertCount == 1 ){        throw new RuntimeException("test transaction roll back");    }    return insertCount;}TransactionTestServiceImpl:@Transactionalpublic void test() {    try {        userService.insertUser("abc", "123");    } catch (Exception e) {        //do Nothing    }    userMapper.updateUserPassWord(1L, "456");}

程序正常运行,因为NESTED内部事务回滚不影响外部事务。假如这个时候我们把test的@Transactional去掉再运行test方法,发现insertUser没有插入用户信息,说明当前没有事务的情况下,NESTED会默认创建一个事务,类似于REQUIRED。

如果我们把程序改为下面的情况:

UserserviceImpl:@Transactional(propagation = Propagation.NESTED)public int insertUser(String name, String password) {    User user = new User();    user.setPassword(password);    user.setUsername(name);    int insertCount =  userMapper.insertEntity(user);    return insertCount;}TransactionTestServiceImpl:@Transactionalpublic void test() {    userService.insertUser("abc", "123");    int updateRow = userMapper.updateUserPassWord(1L, "456");    if (updateRow == 1) {        throw new RuntimeException("transational roll back");    }}

我们会发现没有插入用户信息,当前事务和子事务全部回滚。

结论:

NESTED子事务回滚不会影响当前事务的提交(catch回滚异常的情况下),但是当前事务回滚会回滚子事务。也就是说只有当前事务提交成功了,子事务才会提交成功。

四、Propagation.REQUIRED_NEW的测试

UserserviceImpl:@Transactional(propagation = Propagation.REQUIRES_NEW)public int insertUser(String name, String password) {    User user = new User();    user.setPassword(password);    user.setUsername(name);    int insertCount =  userMapper.insertEntity(user);    return insertCount;}TransactionTestServiceImpl:@Transactionalpublic void test() {    userService.insertUser("abc", "123");    int updateRow = userMapper.updateUserPassWord(1L, "456");    if (updateRow == 1) {        throw new RuntimeException("transational roll back");    }}

运行结果:程序报错,但是有用户信息插入。

将程序改为下面的样子:

UserserviceImpl:@Transactional(propagation = Propagation.REQUIRES_NEW)public int updateUserPassWorld(Long id, String password) {    int update =  userMapper.updateUserPassWord(id,password);    return update;}TransactionTestServiceImpl:@Transactionalpublic void test() {    //当前事务    userMapper.updateUserPassWord(28L, "123456");    //执行REQUIRES_NEW事务    userService.updateUserPassWorld(28L, "000000");   System.out.println("commit");}

执行程序,发现程序迟迟没有打印字符串commit,发生了死

结论:

REQUIRES_NEW会启用一个新的事务,事务拥有完全独立的能力,它不依赖于当前事务,执行时会挂起当前事务,直到REQUIRES_NEW事务完成提交后才会提交当前事务,如果当前事务与REQUIRES_NEW 存在锁竞争,会导致死锁。

五、NOT_SUPPORTED的测试

UserserviceImpl:@Transactional(propagation = Propagation.NOT_SUPPORTED)public int updateUserPassWorld(Long id, String password) {    int updateRow =  userMapper.updateUserPassWord(id,password);if(updateRow ==1 ){    throw new RuntimeException("roll back test");}return updateRow;}TransactionTestServiceImpl:@Transactionalpublic void test() {    userService.updateUserPassWorld(28L, "000000");}

程序运行报错,但是id为28的用户密码还是更新了。

将程序改为下面这个情况:

UserserviceImpl:@Transactional(propagation = Propagation.NOT_SUPPORTED)public int updateUserPassWorld(Long id, String password) {    int update =  userMapper.updateUserPassWord(id,password);    return update;}TransactionTestServiceImpl:@Transactionalpublic void test() {    //当前事务    userMapper.updateUserPassWord(28L, "123456");    //执行REQUIRES_NEW事务    userService.updateUserPassWorld(28L, "000000");   System.out.println("commit");}

执行程序,发现程序迟迟没有打印字符串commit,发生了死锁。

结论:

NOT_SUPPORTED会挂起当前事务,并且NOT_SUPPORTED定义的方法内部不启用显示事务,如果NOT_SUPPORTED和当前事务存在锁竞争,会发生死锁。

六、NOT_SUPPORTED的测试

UserserviceImpl:@Transactional(propagation = Propagation.MANDATORY)public int updateUserPassWorld(Long id, String password) {    int updateRow =  userMapper.updateUserPassWord(id,password);    return updateRow;}TransactionTestServiceImpl:public void test() {    userService.updateUserPassWorld(28L, "123456");}

程序运行错误:

org.springframework.transaction.IllegalTransactionStateException: No existing transaction found for transaction marked with propagation ‘mandatory’

结论:

MANDATORY必须包含在事务中,如果事务不存在,则抛出异常

以上就是关于“Spring七大事务传递机制的实现原理是什么”这篇文章的内容,相信大家都有了一定的了解,希望小编分享的内容对大家有帮助,若想了解更多相关的知识内容,请关注编程网精选频道。

--结束END--

本文标题: Spring七大事务传递机制的实现原理是什么

本文链接: https://www.lsjlt.com/news/353457.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Spring七大事务传递机制的实现原理是什么
    这篇“Spring七大事务传递机制的实现原理是什么”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Spring七大事务传递机制...
    99+
    2023-07-05
  • Java参数传递机制的原理是什么
    这篇文章主要介绍“Java参数传递机制的原理是什么”,在日常操作中,相信很多人在Java参数传递机制的原理是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Java参数传递机制的原理是什么”的疑惑有所帮助!...
    99+
    2023-06-18
  • Spring事务的七种传播行为是什么
    本篇内容介绍了“Spring事务的七种传播行为是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!一、什么是事务传播行为什么叫事务传播行为?...
    99+
    2023-06-30
  • android点击事件传递机制是什么
    Android中的点击事件传递机制是基于View的层次结构进行的。当用户触摸屏幕时,Android系统会将触摸事件传递给最上层的Vi...
    99+
    2023-08-18
    android
  • MySQL事务隔离机制与实现原理是什么
    这篇“MySQL事务隔离机制与实现原理是什么”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“...
    99+
    2022-11-30
    mysql
  • android点击事件传递机制怎么实现
    Android的点击事件传递机制是通过View的dispatchTouchEvent方法和onTouchEvent方法实现的。首先,...
    99+
    2023-10-20
    android
  • android中事件分发机制的实现原理是什么
    android中事件分发机制的实现原理是什么,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。android中的事件处理,以及解决滑动冲突问题都离不开事件分发机制,androi...
    99+
    2023-05-30
    android
  • redis实现事务的原理是什么
    这篇文章主要介绍redis实现事务的原理是什么,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!原子性(atomicity):一个事务是一个不可分割的最小工作单位,要么都成功要么都失败。...
    99+
    2024-04-02
  • node中事件机制的原理是什么
    今天就跟大家聊聊有关node中事件机制的原理是什么,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。Publish/Subscribe(发布/订阅模式)...
    99+
    2024-04-02
  • innodb事务实现原理是什么
    InnoDB事务实现原理是通过使用多版本并发控制(MVCC)和日志重做(Redo)来确保事务的原子性、一致性、隔离性和持久性。1. ...
    99+
    2023-09-15
    innodb
  • Java Spring AOP源码解析中的事务实现原理是什么
    这篇文章将为大家详细讲解有关Java Spring AOP源码解析中的事务实现原理是什么,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。不用Spring管理事务?让我们先来...
    99+
    2023-06-22
  • java反射机制的实现原理是什么
    Java反射机制是指在运行状态中,对任意一个类都能够知道这个类的所有属性和方法,对任意一个对象都能够调用它的任意一个方法。实现Jav...
    99+
    2023-08-08
    java
  • 浅析Spring的事务实现原理
    目录SQL事务实现简介编程式事务声明式事务注释事务属性源事务拦截器Bean工厂事务属性源指导事务多样性支持总结SQL事务实现简介 首先我们来了解下,最简单的事务是怎么实现的呢?以JD...
    99+
    2022-11-13
    Spring事务原理 Spring事务
  • 深入理解Spring事务及传播机制之原理解析与实际应用
    目录事务概述事务管理事务传播机制事务传播机制实现框架源码解析总结Spring 框架是一个流行的Java应用程序框架,其中事务管理是其最重要的特性之一。事务是指一系列相关操作的集合,如...
    99+
    2023-05-16
    Spring事务及传播机制 Spring事务管理 Spring传播机制
  • AngularJS 事件发布机制的原理是什么
    AngularJS 事件发布机制的原理是什么,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。未读消息提醒当器具用户或技术机构对非...
    99+
    2024-04-02
  • mysql事务特性的实现原理是什么
    MySQL事务特性的实现原理是通过使用日志和锁机制来保证事务的原子性、一致性、隔离性和持久性。1. 原子性:MySQL使用redo日...
    99+
    2023-10-12
    mysql
  • 数据库事务的实现原理是什么
    本篇内容主要讲解“数据库事务的实现原理是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“数据库事务的实现原理是什么”吧!数据库的事务有四大特性:原子性、隔离性...
    99+
    2024-04-02
  • node.js中事件轮询机制的原理是什么
    node.js中事件轮询机制的原理是什么,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。借助libuv库实现的概括事件轮询机制:分为六个阶段...
    99+
    2024-04-02
  • kubernetes资源QOS机制实现原理是什么
    本篇内容主要讲解“kubernetes资源QOS机制实现原理是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“kubernetes资源QOS机制实现原理是什么”吧!QOS是k8s中一种资源保护...
    99+
    2023-06-19
  • PostgreSQL的事务管理机制是什么
    PostgreSQL的事务管理机制是基于ACID(原子性、一致性、隔离性、持久性)特性的。它支持事务的原子性,即事务中的所有操作要么...
    99+
    2024-04-09
    PostgreSQL
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作