• 后端技术盲区大清理:事务还没弄明白的小伙伴赶紧来看一看


    大家都知道,现在的互联网后端服务总共分3层:dao层、service层和controller层。今天我们来学习一下dao层与service层之间的数据访问问题,看看它们之间是怎么交互的。

    dao层与service层之间的交互,简单说来,就是service层会去调用dao层,而在调用dao层的时候就必然要用到事务。有些新手朋友在初次写后端程序的时候,往往不知道这里有事务问题,以为就像直接调用API一样,调用一次insert/update/delete操作就修改一次数据库,十分简单明了,而且测试也没发现问题,一切正常。其实这样写的程序主要运行在内网、小规模系统环境中,甚至单机运行,这对数据一致性要求不那么高,所以未出错。但是一旦部署到线上高并发运行环境中去,数据很有可能不一致,这是因为没有处理好事务。

    另外,后端服务DAO层一般是接入或使用了ORM框架的,例如Hibernate、JPA、MyBatis等。这些框架主要目的是减少样板代码,提高开发效率。这些不同ORM框架的设计差异很大,却能被Spring框架定义成一套通用的接口,封装起来供我们使用(题外话:不得不说,Spring开发者的抽象化和设计能力真的非常强,值得学习)。

    Spring 事务管理

    spring的事务管理特别强大,优势如下:

    1. 统一的编程模型支持多种不同的事务API,包括JTA、JDBC、Hibernate、JPA等。

    2. 声明式事务管理功能:即只需要声明,加一个注解就搞定一切了。让事务功能用起来简单。

    3. 编程式事务管理:Spring对底层的事务API进行了抽象和简化。

    4. 能够高效集成到Spring的数据访问抽象架构中去,即Spring里面的DAO。

    Spring事务模型

    真正的高手是如何解决问题的?他们不是见到一个问题就写一段代码,然后再加上一大堆的条件判断来限制使用场景。这种解决问题的方式是很原始的。高手则是全面分析问题,把问题中出现的事情进行抽象化,形成一个个的概念,然后再建立起一套模型,把问题统统归类到新建立起的模型上,最后再针对模型来进行分析、求解和计算。

    Spring为了把不同的底层事务API统一,就建立了一个模型,我们姑且叫它为Spring事务模型吧。Spring事务模型是怎么得来的呢?从Java EE中的全局事务和局部事务发展而来。

    在Spring之前,后端服务是基于Java EE的。而在Java EE中,数据库事务功能只有2个选择:1. 全局事务 2.本地事务。

    Java EE 全局事务

    Java EE中的全局事务可以管理多个事务资源,例如关系数据库和消息队列,是跨多台机器的,也就是所谓的“分布式事务”。业务服务器通过JTA管理全局事务(API复杂、难用),而且其中用到的UserTransaction必须是从JNDI拿到,导致必须使用JNDI技术。

    Java EE 局部事务

    局部事务只能管理一个事务资源,不能跨机器,且应用服务器不参与事务管理。大部分流量小的或内网访问的数据管理系统,使用的是局部事务。

    理解Spring框架事务抽象

    事务策略(transaction strategy):这是理解Spring事务抽象的关键。事务策略由TransactionManager定义。

    调用TransactionManager#getTransaction,可以传入TransactionDefinition,可以得到TransactionStatus。

    TransactionStatus:代表了一个新创建的事务或者已经存在的事务。

    TransactionDefinition:指定各种与事务相关的信息。

    1. 传播性 (propagation):凡是在事务范围内的代码,都是在这个事务内运行的。对于一段事务代码来说,假如一个事务已经存在了,需要用传播性来指定是:继续使用已经存在的事务还是把已经存在的事务suspend然后再新建一个事务(Spring事务传播性的概念其实来自EJB CMT,共有5个,可以在TransactionDefinition的源码中找到)

    2. 隔离性(isolation):当前事务与其他事务的隔离的程度。例如,当前事务能够访问到其他事务的还没有提交的数据(参考Isolation枚举类)。

    3. 超时(timeout):事务执行了多长时间之后依然还没有完成,则自动回滚。

    4. 只读(read-only):如果事务只读不修改数据,则可以利用这个参数优化性能。

    上面4项是事务的核心概念,也是后端程序员必然要掌握的基础知识(面试当然会问),掌握不好的话,写出来的代码访问数据库的时候会出问题。

    TransactionStatus可以用于控制事务的运行,还可以查询事务的状态。

    TransactionManager负责执行事务,它与底层用到的数据库框架相关,例如JDBC、JTA、Hibernate分别对应不同的事务管理器(事务管理器)。一般都是Spring预先写好的。例如,如果底层是通过JDBC访问数据库的,那么事务管理器应该用 DataSourceTransactionManager。TransactionManager一般需要依赖一个DataSource,而DataSource一般提供与数据库相关的更加底层的信息,包括jdbcref、用户名、密码等等。

    到这里,你的认知应该有以下迭代了:


    希望这篇文章能对您有帮助!如果您对互联网、前/后/客户端、架构/分布式/高可用/高并发/高实时、电商、Redis、MySQL、Zookeeper、Spring、Android、浏览器插件、Java、C/C++、Linux、个性化推荐、社区发现、机器学习、数据挖掘等感兴趣,欢迎关注。

  • 相关阅读:
    数字化外协生产综合管理系统,实现信息自动同步,数据自动统计分析!
    微信小程序文件上传wx.uploadFile
    IMX6ULL移植篇-boot 命令的学习
    螺旋矩阵问题C代码
    微信小程序之个人中心授权登录
    基于Java+微信小程序实现《优购电商小程序》
    网络渗透测试(wireshark 抓取QQ图片)
    nn.functional.interpolate
    学习记录609@python实现数据样本的过采样与欠采样
    资源:加快进入区块链的5种最佳编程语言
  • 原文地址:https://blog.csdn.net/m0_72730471/article/details/126034817