数据库在数据导入时的并发问题(使用myBatis)

我有一个批量导入数据到数据库中的程序,代码主要做2件事情.

1.首先检查数据库中有无重复记录.如果有则返回false,不进行导入操纵.

2.没有重复数据,则导入这批数据.

现在我有这样一个疑问,当我做完检查的时候,系统发现没有重复,于是执行下面的导入操作.

可当我还没提交这批数据时,另一个系统修改了数据库,导致出现重复记录,也就是说出现了数据不一致的问题.

明明在检查的时候没有重复,可在提交的时候出现重复.象这种问题应该怎么解决,或者此类问题的解决思路是怎样的?

是在检查数据有无重复时就锁住整张表?如果要锁表,myBatis里应该怎么做呢?

0

4个回答

  1. 行锁只能针对已经存在的记录,对于insert数据来说,行锁是无效的;
  2. 表锁是可以的,但是操作太重了,效率会很低;

建议使用如下两种方式之一:

  1. 如果记录本身有主键类的标识的话,将这个字段的唯一性设置为True,这样两线程的insert相同记录就会有一个导致失败,Catch这个Exception就可以了,这个方法比较简单;

  2. 使用分布式锁,如果题主对Zookpeeper有了解的话可以通过Zookeeper设置加一个分布式锁(比如使用insert的主键标识拼接成为一个path,在insert之前获取锁,insert之后释放锁)

前提是需要有能够设别两条记录是同一条记录的手段。

0

select for update 可以锁住那一行

或者你多加一个正在导入的状态是最好的

0

典型的事物隔离级别的问题

将Connection的隔离级别设置为 "不可重复读"

connection.setTransactionIsolation(Connection.TRANSACTION_REPEATABLE_READ)即可

conn.setTransactionIsolation(Connection.TRANSACTION_REPEATABLE_REA)

1查询数据库的状态 //查询的时候会帮当前数据行锁住

2批量保存

conn.close()

0
s_help
s_help 基本搞清楚了,谢谢你的启发,以前有这方面的积累,翻书找到了答案。
接近 6 年之前 回复
s_help
s_help 好像隔离级别应该是不允许幻读,比不可重复读更高一级,不可重复读是原来的数据被修改导致两次读取不一致,幻读是新增加了数据导致两次读取不一致,前者需要行级锁,而幻读则需要表级锁。看来导数据的确影响系统性能啊,导数据的事务期间需要把整个表都锁起来。
接近 6 年之前 回复
s_help
s_help 对隔离级别有一些认识,现在的纠结是,这个隔离级别,能保证不被插入新行么.也就是说行不被修改,我能理解,然后他还能保证行不被添加?是这样么?一直在这个插入新行上无法突破心中的纠结,一直觉得要用锁住整表的那个隔离级别。
接近 6 年之前 回复

第一个答案很好,解释的很到位。

0
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
其他相关推荐
mybatis乐观锁解决高并发时遇到的问题
记录实现通过version机制实现乐观锁时问题, 当做更新操作时,传入version号,由于考虑了接口的公用性所以在xml文件中使用了<if>标签判断是否传入了version, 这使得锁机制被破坏,无法实现乐观锁,将version传成必传不使用<if>标签,version生效,,不知所以然,有大神知道的么,,望解答...
MyBatis数据持久化(四)类型别名
Mybatis的类型别名指的是我们可以为Java类型自定义一个简短的名字,以达到简化配置的目的,在上篇博文中我们的sql语句配置文件内容如下:<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybat
并发insert情况下会发生重复的数据插入问题
并发insert情况下会发生重复的数据插入问题 1.背景    用多线程接收推送的订单数据,把接收的订单数据存到一个表中,实现的需求是:如果接收的订单消息在数据库中已经存在,那么执行update操作;如果没有存在,那么执行insert操作  代码逻辑:     if(该订单在数据库表中存在){ update(); }else{ insert(); }
spring + mybatis + maven实现高并发秒杀业务(一)
前言    刚过了“双十一”,相信大家的待收货都是满满哒,在“双十一”期间,相信很多童鞋都参加了产品“秒杀”吧,12点时候在手机或电脑上抢商品抢的不亦乐乎。但是作为一名可爱的程序猿,就在思考这个秒杀是怎么做出来的啦。废话不多说,下面我们就用一个最简单的demo来实现商店购物的秒杀实现。 创建项目和依赖 1.使用maven命令创建项目   mvn archetype:generate
悲观锁和乐观锁
悲观锁 正如其名,它指的是对数据被外界(包括本系统当前的其他事务,以及来自外部系统的事务处理)修改持保守态度 悲观锁大多数情况下依靠数据库的锁机制实现 要使用悲观锁,我们必须关闭mysql数据库的自动提交属性,因为MySQL默认使用autocommit模式,也就是说,当你执行一个更新操作后,MySQL会立刻将结果进行提交。 我们可以使用命令设置MySQL为非autocomm...
mybatis的sqlsession如何控制并发
目前看mybatis源码时,看到一个问题,关于并发的。 问题连接: [url]http://www.iteye.com/problems/99255[/url] 问题大概描述为: 目前看mybatis源码时(看的很浅)一个问题一直没搞明白,我这边是主流的spring+mybatis。 问题如下: 每个dao都继承了 SqlSessionDaoSupport,而dao操作数据库的时候是...
springmvc+mybatis +poi实现导入exce数据l到数据库中
1.项目用到的是poi技术,需要在maven文件添加如下配置: org.apache.poi poi 3.14 org.apache.poi poi-ooxml 3.6 2.在springMVC.servlet.xml配置bean: <bean id="multipartResolver" class="org.sprin
Java向数据库中插入大量数据时的优化
Java向数据库中插入大量数据时的优化
关于在用mybatis对Oracle数据库进行导入excel表,和批量插入过程中遇到的问题
之前没怎么学过表的导入,但是项目中有个表格导入的功能,所以这两天花点时间把它搞出来了,首先是从前端倒过来,后台对表里面的字段给查出来,"devName:设备名称:" , "devNum:设备编号", "devicetype:设备类型", "siteId:站点ID","installType:安装类型" 像devName等,是给表里面的数据起的别名,最后全部放进一个list里面再向后面传递,在传递
mybatis 数据插入返回主键与多线程运行产生的错误
今天在码代码时,发现一个错误,有时正常有时不正常,完全没有一个程序该有的节操。在一翻调教下正常了。现留下解决方法备用。 以下原理纯属个人臆测,完全没有依据,误导完全不负责任~ 另请明白的大神评论里解释,脆谢~ 目标描述: 我需要一次并行运行多个线程,使用CyclicBarrier 线程阻塞,等待全部执行完毕。每一个执行的线程调用外部接口并收到接口响应,且都有单独的日志信息的DB插入。日志信息...
mybatis并发数据库报错,数据库操作对象已关闭
最近在使用mybatis做数据库管理的时候出现了一个问题,因为只是一个控制台项目,所以没有整合spring,只是用了mybatis默认的一些数据库配置信息。 然后再与前端做交互的时候前端并发访问总是会出现这几个错误: Cannot commit, transaction is already closed ### Cause: org.apache.ibatis.executor.Execu
事务的几种并发问题
以下内容均截取自–spring3.0企业应用开发实战。 作者关于这点的问题,总结的很好,例子也很好。
MyBatis 3.2.x版本在并发情况下可能出现的bug及解决办法
我们基于Spring的Web项目使用的MyBatis版本是3.2.3,有一天忽然发现出现了很神奇的异常,如下: org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.builder.BuilderException: Error evaluating expression 'searchP
MySQL高并发下读取脏数据问题的解决方案
MySQL 在遇到高并发读写的情况下会读到脏数据,如何理解?举一个简单的栗子: 用户A、用户B、用户C 抢购一件商品,每人限购一件,商品库存为10,假如 A、B、C 并发情况下则同时得到 库存为 10,同时对库存10进行操作,看下相关示意图: 用户A 操作: 库存 10 -1 =9,对应的 SQL: update table set goods_number=goods_
selectKey获取最新操作的主键id,支持高并发
描述 有时候操作数据库的时候我们对某个表插入一条记录的时候,记录的主键是一个自增序号id。(因此没有插入id,一般也不用知道id) 但是插入成功后我们又要那个id来做另一些dao操作,比如插入这个id作为外键的关系表记录。想要获取这个id就很麻烦了,而且数据库操作并发量很多, 就很多意外了。 因此MyBatis提供了一个简单的&amp;lt;selectKey&amp;gt;获取最新id, 而且有针对用户的同步...
数据库高并发插入数据导致的主键冲突问题解决
现代系统都是数据驱动的业务系统,所有的系统都离不开数据,我们现在存储的大部分还是通过关系型数据库来存储的,因为关系型数据库的锁可以保证数据的一致性,所以我们大部分的数据会持久化到数据库中,但是往往数据计算过程比较复杂,都是经过各个应用计算之后的数据,直接操作还不是很方便,所以我们的数据都是通过应用存储到数据库中的,那么问题来了,假如系统高并发运行,同时又两条数据同时执行insert会出现什么,后执...
MySQL中SELECT+UPDATE处理并发更新问题解决方案分享
这篇文章主要介绍了MySQL中SELECT+UPDATE处理并发更新问题解决方案分享,需要的朋友可以参考下 问题背景: 假设MySQL数据库有一张会员表vip_member(InnoDB表),结构如下:   当一个会员想续买会员(只能续买1个月、3个月或6个月)时,必须满足以下业务要求: •如果end_at早于当前时
高并发架构实战(三) Spring Boot 集成 mybatis-plus
Spring Boot 2.0.4 集成 mybatisplus-spring-boot-starter 1.0.5 。 1. 初始化工程 项目源码地址 工程 user-provider的结构为: $ tree -I target . ├── pom.xml └── src └── main ├── java │ └── cn │ ...
java代码SpringBoot集成mybatis实现excel表格与mysql数据库交互数据
springboot集成mybatis简单demo实例,实现excel表格与mysql数据库的数据交互(test测试实现),springboot+mybatis项目的简单操作(注解+mybatisxml文件配置)
Mysql并发插入,存在更新,不存在新增
在实际开发过程中,我们会遇到这样的问题,插入数据时想让数据库存在的时候就更新,不存在的时候就新增。方案一:先查询后插入,先到数据库查询一下,查到数据就更新,查询不到数据就新增,但是这种情况往往会发生很多错误,比如在查询后判断是否存在时,其他线程已经插入完毕了,你这边还是判断不存在的,这时候就会重复插入或者报错。方案二:Mysql提供了ON DUPLICATE KEY UPDATE,保证了操作的原子...
开发中遇到的并发和数据库问题
1并发问题1.1:一个状态修改引起的问题 1.2:本地和服务器因为同一个状态撕咬后的解决方案 2数据库问题2.1:一个状态修改引起的问题 2.2:安卓能支持Sqlite多线程操作吗 2.3:临时文件的产生与解决 2.4:数据库主键的选择 2.4:为什么要加索引 并发问题一个状态修改引起的问题        就是我们本地做了同步和异步两种操作,每个操作都会牵扯到对某个状态的修改,判断,展示。除此之外,
利用Spark把数据写进mysql数据库时候遇到的问题
写入数据库的方式是:df2.write.mode(SaveMode.Append).jdbc(url,&quot;student&quot;,properties)impossible to write to binary log since BINLOG_FORMAT = STATEMENT这是因为,mysql默认的binlog_format是STATEMENT。从 MySQL 5.1.12 开始,可以用以下三种模...
Java之:事务
一、文章来由事务在金融领域用的是非常之多的,所以现在非常重要,比如一个事务是“A给B转账500块”,但这个步骤至少有:(1)扣除A的500 (2)增加B的500如果这两部分不是一起完成,就会有资损发生。二、什么是事务 事务指的是逻辑上的一组操作,这组操作要么全部成功,要么全部失败。 一般的事务指的都是数据库事务,但是广义事务的定义不局限于数据库事务。三、事务的特性事务有4大特性,即 ACID。
高并发,业务量大的业务场景下,数据库减库存的解决方案
一,用户下单购买商品的情况下,如果有多个人同时下单,减除库存的情况下,如果遇到了减去库存的并发问题,这个时候应该怎么处理呢? 传统的业务流程场景下,处理流程是这样的:1,库存查询,通过dao查询商品库存,返回库存数量 select stock from goods where gid=#{gid} 2,逻辑判断库存是否充足,充足进行库存减扣 update stock set stock=stoc...
记录一次并发导致的钱包金额不一致,后者覆盖前者
使用的是hibernate  JPA, mysql 5.6 假设           线程T1读取钱包金额为100同时       线程T2也读取钱包金额为100T1  增加钱包金额10,  钱包金额=110;T2  增加钱包金额5 ,   钱包金额=105;此时 T1  update    数据库记录为110;T2随后 update     此时会将T1修改的数据给覆盖 为 105;问题就出现了...
Springboot2+Mybatis-Mysql-基于rabbitMQ实现在高并发下性能倍增
项目说明: 1.订单超时处理,用redis的zset有序集合来做 2.基于rabbitMQ实现在高并发下性能倍增   项目结构 第一步:新建maven项目 第二步:配置pom文件 &amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&amp;gt; &amp;lt;project xmlns=&quot;http://maven.apache.org/POM/4.0.0&quot; ...
大数据量高并发的数据库优化
一、数据库结构的设计       如果不能设计一个合理的数据库模型,不仅会增加客户端和服务器段程序的编程和维护的难度,而且将会影响系统实际运行的性能。所以,在一个系统开始实施之前,完备的数据库模型的设计是必须的。       在一个系统分析、设计阶段,因为数据量较小,负荷较低。我们往往只注意到功能的实现,而很难注意到性能的薄弱之处,等到系统投入实际运行一段时间后,才发现系统
高并发下数据库插入重复数据
方法1: [code=&quot;java&quot;]ServiceA{ // 根据username查询数据库中是否存在该数据 Method isInDB(String username); //保存用户 Method saveUser() { boolean flag = Method isInDB(username); ...
MySQL并发导致的脏数据分析
记录一下一个并发导致的脏数据问题(基于MySQL)。问题描述(银行操作员例子):比如A、B操作员同时读取一余额为1000元的账户,A操作员为该账户增加100元,B操作员同时为该账户扣除50元,A先提交,B后提交。最后实际账户余额为1000-50=950元,但本该为1000+100-50 = 1050 。 首先分析下如何会导致问题的出现: 我们来些一个伪代码表示下A操作员操作执行的过程:
Mysql数据库并发插入死锁问题及处理方式
Mysql有很多坑,对Mysql多线程支持这块不是很熟的话就会莫名其妙地发生一些诡异的问题。多线程线程并发操作时最容易产生死锁问题。所以很多大数据的操作一般都采用NoSQL数据库方案来处理,或者读写分离,只需要做好幂等设计即可。
数据库并发操作会带来哪些问题及原因
(1)丢失更新         当两个或多个事物读入同一数据并修改,会发生丢失更新问题,即后一个事物更新的结果被前一事务所做更新覆盖 即当事务A和B同事进行时,事务A对数据已经改变但并未提交时B又对同一数据进行了修改(注意此时数据是A还未提交改变的数据),到时A做的数据改动丢失了 (2)不可重复读       当两个数据读取某个数据后,另一事务执行了对该数据的更新,当前一事务再次读取该数据(
并发问题可能导致的脏数据
在整理应用中旧系统数据移植的问题,发现表中出现了几条异常记录,记录除主键不同外,记录的时间和其它内容完全一致。 业务本身的逻辑是,如果碰到数据库中有相关的记录需要把这些记录置为无效,然后插入一条记录。现在是出现了二条有效的记录,是违背业务逻辑本意的。 猜测问题可能出在 1、重复提交表单引起的 2、两个人同时进行相同的操作引起的 3、由于生产环境使用了集群,当不同的人访问不同的集群上...
非常详细的用 java(springmvc+mybatis)实现excel导入功能并且保存到数据库
springmvc+mybaits实现excel导入功能,整理非常详细,欢迎下载参考使用
多线程-并发与锁
我们讲到多线程,就离不开并发,讲到并发,就离不开安全性,这里我们先来实现一个简单功能能:买票系统   这是票的类,以及买票的方法: public class DBTicket { // 假设存放100张票 private static int num = 100; public static void setNum(int num) { DBTicket.num = n...
项目中遇到的经典问题1==同步登录的数据,高并发的时候会出现同步两条相同数据
MongoDB常见问题 —— 并发
前言 MongoDB允许多个客户端读取和写入相同的数据。 为了确保一致性,它使用lock和其他并发控制措施来防止多个客户端同时修改同一条数据。 总之,这些机制保证对单个文档同时只可能被一个客户端写入,并且客户端永远不会看到数据的不一致视图。 MongoDB使用什么类型的锁? MongoDB使用多粒度锁,允许操作锁定全局,数据库或集合级别,并允许各个存储引擎在集合级别下实现自己的并发控制(例如,在W...
Java模块 -- 读取Excel文件写入数据库 Mybatis , POI , JXL
废话不多说,直接上代码结构图 所用到的lib包 Students 实体类 package com.test.model; public class Students { private int id; private String username; private int age; private int salary; public int get
数据库隔离级别和并发操作可能导致的问题
并发操作可能遇到的问题: 1.读到脏数据,脏数据就是读到了别的事务没有提交的数据, 举个例子,A在一个转账事务中,转了100块钱给B,此时B读到了这个转账的数据,然后做了一些操作(发货给A,或者其他的),可是这时候A的事务并没有提交,如果A回滚了事务,那就GG了。这就是脏读了。2.不可重读读,在一个事务中两次进行读取同一数据,读到的内容不一致(主要是读到了别的事务更改的数据),这个应用场
数据库并发操作带来的问题以及解决方案
数据库并发操作带来的数据不一致性主要有, 丢失修改,不可重复读(里面包括幻读),读脏数据 其中不可重复读有三种情况,后两种称为幻读,幻读和不可重复读的区别是幻读是对数据的删除增添,不可重复读是数据的修改 解决办法 封锁 锁包括 排它锁(X锁)和共享锁(S锁) 封锁带来的问题 :活锁(先来先服务解决),死锁 死锁解决方案:预防死锁,定期检测死锁解除死锁 预防:1 一次封锁法 ,问题降低并
数据库并发下的脏数据问题
事情是这样的,我有个需求,简单来说是每次insert三条记录,每次都给本次insert的记录version+1,理想情况下,假设没有并发,最后的数据应该是这样 id    name        version 1     name           1 2     name           1 3     name           1 4     name