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

大家都知道,现在的互联网后端服务总共分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、个性化推荐、社区发现、机器学习、数据挖掘等感兴趣,欢迎关注。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值