Spring强大事务兼容数据库多种组合解决业务需求

 更新时间:2022年07月25日 14:52:21   作者:zxhtom  
这篇文章主要为大家介绍了Spring强大事务兼容数据库多种组合解决业务需求示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

事物的由来

在mysql中只有innodb存储引擎才支持事物,所以我们后续都是基于innodb来展开的

事物特性

事物是用来保证数据的完整性的,保证批量sql执行的统一性;事物具有四个特性: A(Atomicity)、C(Consistency)、I(Isolation)、D(Durability)

原子性

一个事务(transaction)中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。

一致性

在事务开始之前和事务结束以后,数据库的完整性没有被破坏。这表示写入的资料必须完全符合所有的预设规则,这包含资料的精确度、串联性以及后续数据库可以自发性地完成预定的工作。

隔离性

数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。

持久性

事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。

基于四个特性,我们就需要在数据和性能进行权衡,需要比较下场景。在m y s q l中就存在四种隔离级别。事务隔离分为不同级别,包括读未提交(Read uncommitted)、读提交(read committed)、可重复读(repeatable read)和串行化(Serializable)。

隔离级别脏读(Dirty Read)不可重复读(NonRepeatable Read)幻读(Phantom Read)
未提交读(Read uncommitted)可能可能可能
已提交读(Read committed)不可能可能可能
可重复读(Repeatable read)不可能不可能可能
可串行化(Serializable )不可能不可能不可能
  • 之前我一直错误的认为mysql中默认的是读已提交。后来查阅资料才知道默认的是可重复读隔离级别。

什么事脏读、不可重复读、幻读

上面提到了三种异常数据情况,作为一名合格的程序员我们需要知道不同的隔离级别会给我们造成具体什么样的伤害。

脏读

脏读指的是A事物在操作数据,还未进行提交此时B事物就已经感知到数据的变化了。这是我们最不能接受的。这里以个人举例,大学期间看中一款手机但是囊中羞涩需要爸妈支援下,打电话让爸妈赚钱这里我们理解成A事物,我着急用钱我是B事物,此时A事物向zxh这张表新增了money=5000元的一条数据。B事物在修改zxh这张表中money这个字段。如果我们是读未提交隔离级别。那么A事物刚新增完事物还未提交,B事物却已经可以修改了。那么B事物修改成功后就结束了。这个时候如果A事物因为别的原因出现异常了。那么就需要将add的5000进行回滚,回滚后余额出现负数。这个负数对于银行来说就是坏账。

#### 不可重复读

-   顾名思义就是同一条数据多次读取并不能保证数据一致性。这是因为A事物第一次读完数据后B事物修改了相同的数据行。那么A事物在此读取该数据就会发生不可重复读。

#### 幻读

-   不可重复读是针对同一条数据内容的变化。而幻读针对的是表记录的变化。还是A事物第一次查询数据匹配到10条,第二次相同条件匹配到的是20条。这就是幻读。
复制代码

查询

s q l功能
select @@tx_isolation;查询数据库默认隔离级别
select @@global.tx_isolation;查看系统当前隔离级别
set session transaction isolation level repeatable read;设置当前会话隔离级别
set global transaction isolation level repeatable read;设置系统当前隔离级别
  • mysql 四种隔离级别对应关系 ; 设置时候去掉破折号就行了

REPEATABLE-READ

READ-COMMITTED

READ-UNCOMMITTED

SERIALIZABLE

  • 我们也可以通过show来查看相关配置
show variables like '%iso%';

spring事物

 @Override
 public Map<String, Object> startTransaction(Transmodel transmodel) {
   int insert = transMapper.insert(transmodel);
   log.info("操作日志:" + insert);
   if ("zxhtom".equals(transmodel.getName())) {
     throw new RuntimeException("error");
   }
   return new HashMap<>();
 }
复制代码
  • 上面代码逻辑非常的简单,当我们传送如下参数时就会报错
   {
     "name": "zxhtom",
     "code": "56",
     "age": 34
 }
复制代码
  • 但是呢?我们再去数据库查看,发现该数据进入数据库了。

  • 发生这种场景时不行的,在互联网中我们要求部分接口必须具有原子性,中途报错之前所有的操作就必须回滚。如果我们自己使用jdbc那么直接通过连接对象rollback就行了。
  • 在spring中因为连接session对接管了,我们就不必那么麻烦了,直接通过@Transactional标注我们的方法就可以实现事物了。
 @Transactional
 public Map<String, Object> startTransaction(Transmodel transmodel) {
   int insert = transMapper.insert(transmodel);
   log.info("操作日志:" + insert);
   if ("zxhtom".equals(transmodel.getName())) {
     throw new RuntimeException("error");
   }
   return new HashMap<>();
 }
复制代码
  • 在此执行就会发现,数据并没有新增,这就是我们想要的效果

spring事物有哪些可配项

  • 里面有几个属性我们需要关注下。已经圈出来了。

字段作用
value事物管理器;用于提交和回滚的功能;默认的DataSourceTransactionManager内部时datasource来操作提交回滚的
transactionManager事物管理器;用于提交和回滚的功能;默认的DataSourceTransactionManager内部时datasource来操作提交回滚的
propagation传播属性;spring中方法内方法事物传递属性设置
isolation隔离级别,在数据库基础上新增一个默认以数据库隔离级别为准
timeout超时事物不提交
readOnly这个感觉没啥意义,被标注的方法无法执行更新操作,只能select
rollbackFor导致事务回滚的异常类数组
rollbackForClassName导致事务回滚的异常类名字数组
noRollbackFor不会导致事务回滚的异常类数组
noRollbackForClassName不会导致事务回滚的异常类名字数组

传播属性

  • 传播属性spring为我们建立了枚举
 public enum Propagation {
   REQUIRED(TransactionDefinition.PROPAGATION_REQUIRED),
   SUPPORTS(TransactionDefinition.PROPAGATION_SUPPORTS),
   MANDATORY(TransactionDefinition.PROPAGATION_MANDATORY),
   REQUIRES_NEW(TransactionDefinition.PROPAGATION_REQUIRES_NEW),
   NOT_SUPPORTED(TransactionDefinition.PROPAGATION_NOT_SUPPORTED),
   NEVER(TransactionDefinition.PROPAGATION_NEVER),
   NESTED(TransactionDefinition.PROPAGATION_NESTED);
   private final int value;
   Propagation(int value) {
     this.value = value;
   }
   public int value() {
     return this.value;
   }
 }

以上就是Spring强大事务兼容数据库多种组合解决业务需求的详细内容,更多关于Spring事务解决业务需求的资料请关注脚本之家其它相关文章!

相关文章

  • Spring boot easyexcel 实现复合数据导出、按模块导出功能

    Spring boot easyexcel 实现复合数据导出、按模块导出功能

    这篇文章主要介绍了Spring boot easyexcel 实现复合数据导出、按模块导出,实现思路流程是准备一个导出基础填充模板,默认填充key,本文给大家介绍的非常详细,需要的朋友可以参考下
    2023-09-09
  • 详解Spring MVC4 纯注解配置教程

    详解Spring MVC4 纯注解配置教程

    本篇文章主要介绍了Spring MVC4 纯注解配置教程,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-04-04
  • Lucene 索引删除策略源码解析

    Lucene 索引删除策略源码解析

    这篇文章主要为大家介绍了Lucene 索引删除策略源码解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-03-03
  • JAVA删除字符串固定下标字串的实现

    JAVA删除字符串固定下标字串的实现

    本文主要介绍了JAVA删除字符串固定下标字串的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-04-04
  • Quarkus集成apollo配置中心

    Quarkus集成apollo配置中心

    这篇文章主要介绍了Quarkus集成apollo配置中心,文中详细的讲解了Quarkus的config构成,以及apollo集成实现,有需要的朋友可以借鉴参考下,希望能够有所帮助
    2022-02-02
  • JAVA简单分组的算法实现

    JAVA简单分组的算法实现

    本文介绍了“JAVA简单分组的算法实现”,需要的朋友可以参考一下
    2013-03-03
  • Spring AI 使用本地 Ollama Embeddings的操作方法

    Spring AI 使用本地 Ollama Embeddings的操作方法

    使用 OpenAI 的 Embeddings 接口是有费用的,如果想对大量文档进行测试,使用本地部署的 Embeddings 就能省去大量的费用,所以我们尝试使用本地的 Ollama Embeddings,这篇文章主要介绍了Spring AI 使用本地 Ollama Embeddings,需要的朋友可以参考下
    2024-05-05
  • Java获取磁盘空间的两种代码示例

    Java获取磁盘空间的两种代码示例

    这篇文章主要介绍了Java获取磁盘空间的两种代码示例,没什么事的时候可以拿来玩玩,需要的朋友参考下。
    2017-11-11
  • 详解java如何处理各种批量数据入库

    详解java如何处理各种批量数据入库

    这篇文章主要为大家详细介绍了java如何使用BlockingQueue处理各种批量数据入库,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2023-11-11
  • MyBatis自定义TypeHandler实现字段加密解密

    MyBatis自定义TypeHandler实现字段加密解密

    本文主要介绍了MyBatis自定义TypeHandler实现字段加密解密,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2025-03-03

最新评论