2017.7.7 postgreSQL在插入造成重复时执行更新
参考来自:https://stackoverflow.com/questions/1109061/insert-on-duplicate-update-in-postgresql/1109198#1109198
功能需求:接口定义中包含字段update,当它为true时,批量插入中有记录造成唯一键重复时,不报异常,而是执行更新。
1.接口定义
- {
- "resources":
- [
- {
- "name":"*",
- "display_name": "*",
- "description": "*",
- "service": "*"
- },
- ....
- ],
- "update":"true"
- }
2.代码
原本是通过报的异常 DuplicateKeyException,在catch语句里执行update。但是这样操作有一个问题,后面单独说。
- try {
- resourceDao.insert(resource); } catch (DuplicateKeyException e) {
- // if (StringUtils.equals(update,Constants.KEY_FALSE)) {
- // throw new AuthServiceException(ErrorCode.RESOURCE_DUPLICATE_KEY, new Object[]{resource.getFdResName()}, e);
- // }else if (StringUtils.equals(update,Constants.KEY_TRUE)){
- // resourceDao.update(resource);
- // }
- throw new AuthServiceException(ErrorCode.RESOURCE_DUPLICATE_KEY, new Object[]{resource.getFdResName()}, e);
- } catch (Exception e) {
- throw new AuthServiceException(ErrorCode.RESOURCE_CREATE_FAILED, new Object[]{resource.getFdResName()}, e);
- }
3.SQL语句
示例语句:
- 1 INSERT INTO the_table (id, column_1, column_2)
- 2 VALUES (1, 'A', 'X')3 ON CONFLICT (唯一键) DO UPDATE
- 4 SET column_1 ='A',
- 5 column_2 = 'X';
完整语句:
- <insert id="insert" parameterType="Resource" useGeneratedKeys="true" keyProperty="fdResid">
- INSERT INTO t_resource
- <trim prefix="(" suffix=")" suffixOverrides=",">
- <if test="fdResName != null">
- fd_res_name,
- </if>
- <if test="fdDisplayName != null">
- fd_display_name,
- </if>
- <if test="fdResDesc != null">
- fd_res_desc,
- </if>
- <if test="fdTenantId != null">
- fd_tenantid,
- </if>
- <if test="fdService != null">
- fd_service,
- </if>
- </trim>
- <trim prefix="values (" suffix=")" suffixOverrides=",">
- <if test="fdResName != null">
- #{fdResName,jdbcType=VARCHAR},
- </if>
- <if test="fdDisplayName != null">
- #{fdDisplayName,jdbcType=VARCHAR},
- </if>
- <if test="fdResDesc != null">
- #{fdResDesc,jdbcType=VARCHAR},
- </if>
- <if test="fdTenantId != null">
- #{fdTenantId,jdbcType=INTEGER},
- </if>
- <if test="fdService != null">
- #{fdService,jdbcType=VARCHAR},
- </if>
- </trim>
- <if test="fdUpdate == 'true'">
- ON CONFLICT(fd_res_name, fd_tenantid, fd_service) DO UPDATE
- <set>
- <if test="fdDisplayName != null">fd_display_name = #{fdDisplayName},</if>
- <if test="fdResDesc != null">fd_res_desc = #{fdResDesc},</if>
- <if test="fdService != null">fd_service = #{fdService},</if>
- <if test="fdModifyDate != null">
- fd_modify_date = #{fdModifyDate,jdbcType=VARCHAR},
- </if>
- <if test="fdModifyPerson != null">
- fd_modify_person = #{fdModifyPerson,jdbcType=VARCHAR},
- </if>
- </set>
- </if>
- </insert>
4.遇到的问题
之前提到过,之前的处理是通过所报异常信息来做的。如果重复了,在catch语句里执行update。
- 1 catch (DuplicateKeyException e) {
- 2 if (StringUtils.equals(update,Constants.KEY_FALSE)) {
- 3 throw new AuthServiceException(ErrorCode.RESOURCE_DUPLICATE_KEY, new Object[]{resource.getFdResName()}, e);
- 4 }else if (StringUtils.equals(update,Constants.KEY_TRUE)){
- 5 resourceDao.update(resource);
- 6 }
- 7 throw new AuthServiceException(ErrorCode.RESOURCE_DUPLICATE_KEY, new Object[]{resource.getFdResName()}, e);
- 8 }
但是在插入重复数据时,报了如下错误:
- Caused by: org.postgresql.util.PSQLException: ERROR: current transaction is aborted, commands ignored until end of transaction block
原因是这个类ServiceResource上标记了@Transactional(在没有事务管理的场景下,是可以像上面那样做的):
2017.7.7 postgreSQL在插入造成重复时执行更新的更多相关文章
- 2017.9.15 postgresql批量插入造成冲突后执行更新
参考来自:https://stackoverflow.com/questions/40647600/postgresql-multi-value-upserts/46233907#46233907 1 ...
- 当插入数据失败时,防止mysql自增长字段的自增长的方法
问题描述: 当mysql设置了自增长字段时(注意:一个表中只能设置一个自增长字段,可以不是主键,但必须是键 ),如果插入数据失败,那么自增长字段仍然会占用这个自增长值,再次成功插入数据时就会造成断层. ...
- MYSQL插入处理重复键值的几种方法
当unique列在一个UNIQUE键上插入包含重复值的记录时,默认insert的时候会报1062错误,MYSQL有三种不同的处理方法,下面我们分别介绍. 先建立2个测试表,在id列上创建unique约 ...
- 【转】insert忽略重复、mysql插入操作跳过、插入覆盖覆盖、mysql更新重复
需求背景:一般情况,插入数据的时候,有脏数据的情况,主键重复的话,直接insert into 会报错的,然后下面的sql都不再执行了,如果可以确定后面的数据可以覆盖前面的数据,直接用replace i ...
- sql语句-------重复时插入更新
ON DUPLICATE KEY UPDATE重复时插入更新 insert into user(id,username) value('231',"二人") on duplicat ...
- 跟我一起读postgresql源码(八)——Executor(查询执行模块之——可优化语句的执行)
2.可优化语句的执行 可优化语句的共同特点是它们被查询编译器处理后都会生成査询计划树,这一类语句由执行器(Executor)处理.该模块对外提供了三个接口: ExecutorStart.Executo ...
- 跟我一起读postgresql源码(十)——Executor(查询执行模块之——Scan节点(下))
接前文跟我一起读postgresql源码(九)--Executor(查询执行模块之--Scan节点(上)) ,本篇把剩下的七个Scan节点结束掉. T_SubqueryScanState, T_Fun ...
- 【转】Jmeter中使用CSV Data Set Config参数化不重复数据执行N遍
Jmeter中使用CSV Data Set Config参数化不重复数据执行N遍 要求: 今天要测试上千条数据,且每条数据要求执行多次,(模拟多用户多次抽奖) 1.用户id有175个,且没有任何排序规 ...
- Jmeter===Jmeter中使用CSV Data Set Config参数化不重复数据执行N遍(转)
Jmeter中使用CSV Data Set Config参数化不重复数据执行N遍 要求: 今天要测试上千条数据,且每条数据要求执行多次,(模拟多用户多次抽奖) 1.用户id有175个,且没有任何排序规 ...
随机推荐
- 交叉编译HTOP并移植到ARM嵌入式Linux系统
原创作品,允许转载,转载时请务必以超链接形式标明文章.作者信息和本声明,否则将追究法律责任. 最近一直在完善基于Busybox做的ARM Linux的根文件系统,由于busybox是一个精简的指令集组 ...
- WebSocket贪吃蛇例子学习
在Tomcat7.0.64下的examples文件夹内,有多人贪吃蛇的例子. Multiplayer snake 这是一个多人在线小游戏,客户端通过操作上下左右键指挥自己的蛇,如果碰到别的蛇就死掉.还 ...
- 在本地文件当中package.json的作用
除了常见的指定包的相关依赖,一些包的相关信息之外 main: 它是用来指定当前包的入口文件,容易让人忽视的一点是它不仅仅在发布的npm包当中有用,在你的业务代码当中也具有一样的作用. 例如,我需要一个 ...
- 阿里云Centos 7 FTP(vsftp)服务安装及配置
#检查vsftpd是否安装 rpm -qa | grep vsftpd #检查vsftpd版本并安装 yum list vsftpd yum install vsftpd #设置开机启动 system ...
- codeforce 570 problem E&& 51Nod-1503-猪和回文
1503 猪和回文 一只猪走进了一个森林.很凑巧的是,这个森林的形状是长方形的,有n行,m列组成.我们把这个长方形的行从上到下标记为1到n,列从左到右标记为1到m.处于第r行第c列的格子用(r,c)表 ...
- [ CodeVS冲杯之路 ] P1154
不充钱,你怎么AC? 题目:http://codevs.cn/problem/1154/ 由于所有珠子连成一个环,所以要进行预处理,直接将整个值往后复制 n 位,即 a[i+n]=a[i] 设 f[i ...
- NS_AVAILABLE_IOS(6_0)
http://www.cocoachina.com/bbs/read.php?tid=241951 一个简单的小问题,请诸位大侠帮助给看看 ,新手 ,勿拍砖 本帖属于CocoaChina会 ...
- shell编程学习笔记【原创】
本文为本人学习笔记,如有转载请注明出处,谢谢 一.Bourne Shell 有如下四种变量: 用户自定义变量 位置变量,即命令行参数 预定义变量 环境变量 二.位置变量 $ 与键入的命令行一样,包含脚 ...
- ubuntu14.04LTS openssh-server 手动安装配置步骤
先用能上网的机器下载:zlib-1.2.5.tar.bz2.openssh-5.6p1.tar.gz.openssl-0.9.8o.tar.tar,接下来,准备安装. 步骤如下: 1.首先解压安装zl ...
- Appium+python自动化9-SDK Manager【转载】
前言 SDK Manager到有哪些东西是必须安装的呢? 一.SDK Manager 1.双击打开SDK Manager界面