事务@transactional执行产生重复数据

背景

系统设计之初,每次来新请求,业务层会先查询数据库,判断是否存在相同的id数据(id是唯一标识产品的),有则返回当前数据库查到的数据,根据数据决定下一步动作,没有则认为是初次请求,将数据存入数据库,执行另一个操作。结果最近出现了并发情况下数据库产生了多条重复的数据。这里记录一下相关的思考与解决。

一. 查询数据库有哪些重复记录

方法1—使用group by 和 having子句

原理就是:将待查询列进行分组,并计算出每个分组中的行数,然后使用having子句筛选出大于1的分组返回结果。即为重复的数据列和重复次数。
举例子:查询表中重复的 sn 号列数据

select sn, count(*) as c from device_active_info group by sn having c>1;

结果:
在这里插入图片描述

方法2:使用子查询和 join 查询

方法1我只查询出了重复列字段和重复次数,那么我想查询重复的列对应的整行数据呢?
语法如下:(子查询和join表连接)

select t1.* from device_active_info t1 join (select sn, count(*) as c from device_active_info group by sn having c>1) t2 on t1.sn = t2.sn

结果就可以得到重复列的所有详细数据。

2. 为什么会产生重复记录?

按照常理来说,事务的ACID特性会保证事务的一致性。但是这里是因为:执行事务A的过程中,先查询 sn,不存在再执行插入;因为时间相对较长,事务A执行完操作尚未提交时,事务B也进来执行操作,当查询数据库中是否存在数据sn时,此时同样未查询到,因此两个事务都提交完毕后,就出现了两条sn相同的重复记录。

那么为什么会这样?加@Transactional 注解还不够吗?

不够。

3. 解决方法

方案1 给字段设置唯一索引或联合主键

这样,当插入重复数据时会发生异常,也就不会产生这个问题了。

举例子:我使用navicat给s字段添加unique唯一性约束。
在这里插入图片描述

方案2 使用synchronized 关键字且其作用域包含 proxy事务

这里注意我说的字眼,因为spring事务是基于AOP的,

1. Synchronized在事务注解@Transactional 标注的方法内或方法上

这种情况下锁是失效的。

@Transactional注解实现事务的功能是通过aop的方式实现的,在Synchronized锁生效之前就开启了事务,然后锁关闭,最后再提交事务,在高并发的情况下,存在同步锁关闭,但是事务还未提交,新的线程已经重新获取了同步锁,
数据库数据此时还未更新,新线程读到的数据是旧数据。导致Synchronized同步不生效问题
解决方法:
需要在事务开启之前开启同步锁。可以将Synchronized放置在调用事务函数之前。

在这里插入图片描述

2. Synchronized关键字同步的方法、代码块包含@Transactional事务

这种情况下是可以实现数据唯一的。

我们可以新建一个类,写一个synchronized方法然后内部调用要执行的事务方法。

public Synchronized void doTransaction(sn) {testService.add(sn);
}
---@Override
@transactional
public void add(String sn) {
// 有则更新或不变;无则新增插入数据库
}

MySQL 在写入数据时,可能会出现写入两条相同记录的情况,
原因如下:
重复插入:在插入数据时,如果使用的是 INSERT INTO 语句,但没有设置主键或唯一索引,那么可能会出现重复插入相同数据的情况。这时候,MySQL 不会报错,而是直接插入数据。
多线程写入:如果有多个线程同时写入相同的数据,那么就可能会出现写入两条相同的记录的情况。这种情况下,需要使用事务来保证数据的一致性。
主从同步:在主从复制的环境下,如果主库写入了一条数据,但是还没有同步到从库,而此时主库又写入了一条相同的数据,那么就会出现写入两条相同的记录的情况。
为了避免写入两条相同的记录,可以采取以下措施:
设置主键或唯一索引,避免重复插入相同的数据。
使用事务来保证数据的一致性,避免多线程同时写入相同的数据。
在主从复制的环境下,可以采用延迟复制或者增加从库的数量来提高同步速度,避免写入两条相同的记录。

记几个链接

1、Mysql中重复插入数据不报异常

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/3699.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

销售自动化如何提高团队生产力?从这5个方面发力

任何用于减少人工劳动和缩短销售流程相关任务时间的技术,都可定义为销售自动化。 对于忙碌的销售人员来说,流程自动化是真正的救星。它可以使他们的工作简化30%,让他们更专注于创收任务。这将显著提高团队的工作效率,并带来许多其…

滑动奇异频谱分析:数据驱动的非平稳信号分解工具(Matlab代码实现)

💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…

师承AI世界新星|7天获新加坡南洋理工大学访学邀请函

能够拜师在“人工智能10大新星”名下,必定可以学习到前沿技术,受益良多,本案例中的C老师无疑就是这个幸运儿。我们只用了7天时间就取得了这位AI新星导师的邀请函,最终C老师顺利获批CSC,如愿出国。 C老师背景&#xff1…

Leetcode刷题4

⼆叉树、BFS、堆、Top K、⼆叉搜索树、模拟、图算法 一、二叉树 二叉树的前序中序后序 二叉树节点定义 为了方便演示,我们先定义一个二叉树节点类。 class TreeNode:def __init__(self, val0, leftNone, rightNone):self.val valself.left leftself.right r…

Android ViewGroup onDraw为什么没调用

ViewGroup,它本身并没有任何可画的东西,它是一个透明的控件,因些并不会触发onDraw,但是你现在给LinearLayout设置一个背景色,其实这个背景色不管你设置成什么颜色,系统会认为,这个LinearLayout上…

[回馈]ASP.NET Core MVC开发实战之商城系统(开篇)

在编程方面,从来都是实践出真知,书读百遍其义自见,所以实战是最好的提升自己编程能力的方式。 前一段时间,写了一些实战系列文章,如: ASP.NET MVC开发学生信息管理系统VueAntdvAsp.net WebApi开发学生信息…

R语言的水文、水环境模型优化技术及快速率定方法与多模型案例实践

在水利、环境、生态、机械以及航天等领域中,数学模型已经成为一种常用的技术手段。同时,为了提高模型的性能,减小模型误用带来的风险;模型的优化技术也被广泛用于模型的使用过程。模型参数的快速优化技术不但涉及到优化本身而且涉…

Python中的break和continue语句应用举例

Python中的break和continue语句应用举例 在进行Python编程时候,有时需要,对循环中断或跳过某部分语句,此时常会用到break语句或continue语句。本文将通过实际例子阐述这两个语句的用法。 1.break语句 break语句是实现在某个地方中断循环&a…

Java设计模式之行为型-迭代器模式(UML类图+案例分析)

目录 一、基础概念 二、UML类图 三、角色设计 四、案例分析 五、总结 一、基础概念 迭代器模式是一种常用的设计模式,它主要用于遍历集合对象,提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露该对象的内部表示。 举个简单的…

5分钟给你破解这套10万赞的生产教程,访谈乔布斯的AI对话数字人视频是怎么做的

本期是赤辰第16期AI项目拆解栏目; 底部准备了7月粉丝福利,看完可以领取; 上周给粉丝们讲解AI动图说话月涨粉20万的案例并给出保姆式教程,粉丝反馈很热烈,都觉得AI强大,有些学员给自己账号做视频&#xff…

大数据与视频技术的融合趋势将带来怎样的场景应用?

视频技术和AI技术的融合是一种新兴的技术趋势,它将改变视频行业的运作方式。视频技术和AI技术的融合主要包括以下几个方面: 1)人脸识别技术 人脸识别技术是AI技术的一个重要应用场景。它可以通过对视频中的人脸进行识别和分析,实…

3.9 Bootstrap 分页

文章目录 Bootstrap 分页分页(Pagination)默认的分页分页的状态分页的大小 翻页(Pager)默认的翻页对齐的链接翻页的状态 分页 Bootstrap 分页 本章将讲解 Bootstrap 支持的分页特性。分页(Pagination)&…

Unity平台如何实现RTSP转RTMP推送?

技术背景 Unity平台下,RTSP、RTMP播放和RTMP推送,甚至包括轻量级RTSP服务这块都不再赘述,今天探讨的一位开发者提到的问题,如果在Unity下,实现RTSP播放的同时,随时转RTMP推送出去? RTSP转RTMP…

浙大数据结构第四周之04-树6 Complete Binary Search Tree

题目详情: A Binary Search Tree (BST) is recursively defined as a binary tree which has the following properties: The left subtree of a node contains only nodes with keys less than the nodes key.The right subtree of a node contains only nodes w…

[javascript核心-08] V8 内存管理机制及性能优化

V8 内存管理 V8 本身也是程序,它本身也会申请内存,它申请的内存称为常驻内存,而它又将内存分为堆和栈 栈内存 栈内存介绍 栈用于存放JS 中的基本类型和引用类型指针栈空间是连续的,增加删除只需要移动指针,操作速度…

代码随香录day21

235. 二叉搜索树的最近公共祖先 本题思路: 还是要利用二叉搜索树的特性,中序遍历为有序数组。如果pq两个节点都小于root,那么最近公共祖肯定是在他的左子树,如果都大于那么,肯定就在右子树。然后直接return root 代码…

Linux Ubuntu安装RabbitMQ服务

文章目录 前言1.安装erlang 语言2.安装rabbitMQ3. 内网穿透3.1 安装cpolar内网穿透(支持一键自动安装脚本)3.2 创建HTTP隧道 4. 公网远程连接5.固定公网TCP地址5.1 保留一个固定的公网TCP端口地址5.2 配置固定公网TCP端口地址 前言 RabbitMQ是一个在 AMQP(高级消息队列协议)基…

【前端知识】React 基础巩固(二十七)——Fragment

React 基础巩固(二十七)——Fragment Fragment Fragment 允许将子列表分组&#xff0c;而无需向 DOM 添加额外节点可以采用语法糖<></>来替代 Fragment&#xff0c;但在需要添加 key 的场景下不能使用此短语 import React, { PureComponent, Fragment } from &q…

Echarts 实现温度计

先上图 <div id="mainOne" style="width: 230px;height:130px;"></div> var dom1 = document.getElementById(mainOne) 核心代码 setTemperature(){var dom1 = document.getElementById(mainOne)var dom2 = document.getElementById(mainTw…

正则表达式与文本处理器

文本处理器三剑客&#xff1a;grep&#xff08;查找&#xff09; sed awk 正则表达式&#xff1a;由一类特殊字符以及文本字符所编写的一种模式&#xff0c;处理文本当中的内容 其中的一些字符不表示字符的字面含义&#xff0c;这些字符表示控制或者通配的功能 通配符&…