广告
返回顶部
首页 > 资讯 > 精选 >如何剖析Spring高级事务管理难点
  • 954
分享到

如何剖析Spring高级事务管理难点

2023-06-17 08:06:39 954人浏览 八月长安
摘要

今天就跟大家聊聊有关如何剖析spring高级事务管理难点,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。1、Spring事务传播行为所谓事务传播行为就是多个事务方法相互调用时,事务如何

今天就跟大家聊聊有关如何剖析spring高级事务管理难点,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。

1、Spring事务传播行为

所谓事务传播行为就是多个事务方法相互调用时,事务如何在这些方法间传播。Spring支持7种事务传播行为

PROPAGATioN_REQUIRED(加入已有事务)

如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。这是最常见也是默认的方式。

PROPAGATION_SUPPORTS(跟随环境)

支持当前事务,如果当前没有事务,就以非事务方式执行。

PROPAGATION_MANDATORY(需要事务)

使用当前的事务,如果当前没有事务,就抛出异常。

PROPAGATION_REQUIRES_NEW(独立事务)

新建事务,如果当前存在事务,把当前事务挂起。

PROPAGATION_NOT_SUPPORTED(非事务方式)

以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。

PROPAGATION_NEVER(排除事务)

以非事务方式执行,如果当前存在事务,则抛出异常。

PROPAGATION_NESTED(嵌套事务)

如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与PROPAGATION_REQUIRED类似的操作。

Spring默认的事务传播行为是PROPAGATION_REQUIRED,它适合于绝大多数的情况。假设ServiveX#methodX()都工作在事务环境下(即都被Spring事务增强了),假设程序中存在如下的调用链:Service1#method1()->Service2#method2()->Service3#method3(),那么这3个服务类的3个方法通过Spring的事务传播机制都工作在同一个事务中。

如果在一个ServiceA和a()方法中启动一个线程,在这个新创建的线程中执行ServiceB的事务方法b()。在相同线程中进行相互嵌套调用的事务方法工作于相同的事务中。如果这些相互嵌套调用的方法工作在不同的线程中,不同线程下的事务方法工作在独立的事务中。

2、多种数据持久方法事务管理

如果你采用了一个高端ORM技术(Hibernate,JPA,JDO),同时采用一个JDBC技术(Spring JDBC,iBatis),由于前者的会话(Session)是对后者连接(Connection)的封装,Spring会“足够智能地”在同一个事务线程让前者的会话封装后者的连接。所以,我们只要直接采用前者的事务管理器就可以了。下表给出了混合数据访问技术所对应的事务管理器:

如何剖析Spring高级事务管理难点

1)不同持久方式的事务统一

Spring提供了一个能从当前事务上下文中获取绑定的数据连接的工具类,那就是DataSourceUtils。Spring强调必须使用DataSourceUtils工具类获取数据连接。

 static Connection doGetConnection(DataSource dataSource)

首先尝试从事务上下文中获取连接,失败后再从数据源获取连接;

static Connection getConnection(DataSource dataSource)

doGetConnection方法的功能一样,实际上,它内部就是调用doGetConnection方法获取连接的;

static void  doReleaseConnection(Connection con, DataSource dataSource)

释放连接,放回到连接池中;

static void release Connection(Connection con, DataSource dataSource)

和doReleaseConnection方法的功能一样,实际上,它内部就是调用doReleaseConnection方法获取连接的;

测试demo:

@Service public class TestTranscationServiceImpl implements TestTranscationService {         @Autowired     private TestTranscationDao testTranscationDao;         @Override     @Transactional     public int test(){          testTranscationDao.update1();          testTranscationDao.update2();                 return 0;      }  }
@Autowired     private JdbcTemplate jdbcTemplate;         @Override     public int update1() {          //1.获得数据库连接          Connection con = DataSourceUtils.getConnection(jdbcTemplate.getDataSource());          try {              con.prepareStatement("update grade_info set grade_name='11' where grade_id=1").executeUpdate();          } catch (sqlException e) {              throw new RuntimeException(e);          }finally {              //2如果当前方法没有上下文事务管理,不释放数据库连接会造成数据库连接泄露              //如果存在上下文事务,调用或者不调用数据库连接释放都没有问题              DataSourceUtils.releaseConnection(con, jdbcTemplate.getDataSource());          }          return 0;         }         @Override     public int update2(){          //3.获得数据库连接   和1的数据库连接是同一个连接          Connection con = DataSourceUtils.getConnection(jdbcTemplate.getDataSource());          try {              //4.这种方法取到的数据库连接和 1,3取到的数据库连接不同              Connection conn = jdbcTemplate.getDataSource().getConnection();              conn.close();          } catch (SQLException e) {              e.printStackTrace();          }          return jdbcTemplate.update("update grade_info set grade_name='高中三年级' where grade_id=1");      }

Spring为每个数据访问技术框架都提供了一个获取事务上下文绑定的数据连接(或其衍生品)的工具类和数据源(或其衍生品)的代理类。

如何剖析Spring高级事务管理难点

2)Hibernate和JDBC混合使用注意事项

由于Hibernate一级缓存的原因,在通过save,update,delete等方法操作数据时,并没有真正向数据库发送SQL,只有调用flush()时,Hibernate才会将一级缓存中的状态变化同步到数据库中。

Hibernate的事务管理在提交事务时,会自动调用flush()操作,将一级缓存同步到数据库中,此时才会将产生并向数据库发送SQL语句。

正是因为以上原因的存在,所有在混合使用JDBC和Hibernate时,可能存在丢失更新的问题。

如何剖析Spring高级事务管理难点

在混合使用Hibernate和JDBC时,JDBC的操作不会同步到Hibernate的缓存中(一级缓存及二级缓存),Hibernate缓存中的状态变更也不被JDBC感知。因此混合使用时必须特别关注这一点。

由于混合数据访问技术的方案的事务同步而缓存不同步的情况,所以***用Hibernate完成读写操作,而用Spring JDBC完成读的操作。如用Spring JDBC进行简要列表的查询,而用Hibernate对查询出的数据进行维护。如果确实要同时使用Hibernate和Spring JDBC读写数据,则必须充分考虑到Hibernate缓存机制引发的问题:必须充分分析数据维护逻辑,根据需要,及时调用Hibernate的flush()方法,以免覆盖Spring JDBC的更改,在Spring JDBC更改数据库时,维护Hibernate的缓存。

3、Spring的事务增强限制条件

由于Spring事务管理是基于接口代理或动态字节码技术,通过aop实施事务增强的。

对于基于接口动态代理的AOP事务增强来说,由于接口的方法是public的,这就要求实现类的实现方法必须是public的(不能是protected,private等),同时不能使用static的修饰符。所以,可以实施接口动态代理的方法只能是使用“public”或“public final”修饰符的方法,其它方法不可能被动态代理,相应的也就不能实施AOP增强,也即不能进行Spring事务增强了。

基于CGLib字节码动态代理的方案是通过扩展被增强类,动态创建子类的方式进行AOP增强植入的。由于使用final,static,private修饰符的方法都不能被子类覆盖,相应的,这些方法将不能被实施的AOP增强。所以,必须特别注意这些修饰符的使用,以免不小心成为事务管理的漏网之鱼。

4、Spring事务管理的异常捕捉,事务回滚

spring的事务管理器只对 unchecked exception进行异常回滚,Error和RuntimeException及其子类是unchecked exception.其他exception是checked exception. 

如果在service层中,使用了try ,catch来捕捉异常,导致sevice层出现的异常被 “截留”,无法抛出给事务管理器,这就给事务管理器造成一种假象,就像程序在运行中,没有产生任何问题,因此也就不会对出现 runtimeException进行回滚操作。

看完上述内容,你们对如何剖析Spring高级事务管理难点有进一步的了解吗?如果还想了解更多知识或者相关内容,请关注编程网精选频道,感谢大家的支持。

--结束END--

本文标题: 如何剖析Spring高级事务管理难点

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

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

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

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

下载Word文档
猜你喜欢
  • 如何剖析Spring高级事务管理难点
    今天就跟大家聊聊有关如何剖析Spring高级事务管理难点,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。1、Spring事务传播行为所谓事务传播行为就是多个事务方法相互调用时,事务如何...
    99+
    2023-06-17
  • 如何理解Spring的Hibernate事务管理机制
    如何理解Spring的Hibernate事务管理机制,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。主要讲了Spring 声明式事务让我们从复杂的Hibernate事务处理中...
    99+
    2023-06-17
  • 详细谈谈Spring事务是如何管理的
    目录前言Spring事务抽象PlatformTransactionManager是事务管理器接口常见的事务管理器有以下几种定义事务的一些参数: 7种事务传播特性: 四种事务隔离级别:...
    99+
    2022-11-12
  • 如何在Spring中使用声明式事务管理
    本篇文章为大家展示了如何在Spring中使用声明式事务管理,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。基于TransactionProxyFactoryBean的事务管理配置Spring中配置AO...
    99+
    2023-05-31
    spring 声明式事务管理
  • 如何用Mybatis源码解析事务管理
    如何用Mybatis源码解析事务管理,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。Mybatis事务管理我们可以在mybatis-config.xml中配置事务管理器的实现...
    99+
    2023-06-22
  • 如何分析Linux服务器权限管理中的sudo高级应用
    这篇文章的内容主要围绕如何分析Linux服务器权限管理中的sudo高级应用进行讲述,文章内容清晰易懂,条理清晰,非常适合新手学习,值得大家去阅读。感兴趣的朋友可以跟随小编一起阅读吧。希望大家通过这篇文章有所收获!在Linux系统中普通用户要...
    99+
    2023-06-28
  • Spring 中的事务管理如何使用注解实现配置
    Spring 中的事务管理如何使用注解实现配置?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。使用步骤:步骤一、在spring配置文件中引入<tx:>命名空间&l...
    99+
    2023-05-31
    spring 注解 事务管理
  • 如何浅析mysql事务和隔离级别底层原理
    本篇文章给大家分享的是有关如何浅析mysql事务和隔离级别底层原理,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。前言首先回顾一下什么是事务,事务是数据库操作的最小工作单元,是作...
    99+
    2023-06-21
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作