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个,且没有任何排序规 ...
随机推荐
- Codeforces Round #357 (Div. 2) C
C. Heap Operations time limit per test 1 second memory limit per test 256 megabytes input standard i ...
- cocos2d-iphone 与 UI组件
http://zhidao.baidu.com/link?url=v9d7y2doWqcPhKz1lz8TkO7ZQfslg-e-55JE0XP9VdKJ0vHobcLPEAXaXjD2lD-TGmg ...
- (二十)linux中i2c的ioctl,write,read函数的使用
一.ioctl函数的使用:原型:struct ioctl(struct file *file,unsigned int cmd,unsigned long arg);cmd有I2C_SLAVE,I2C ...
- Python3在Windows安装配置及简单试用
1,安装配置 安装版本是Python3.5,我的安装路径是E:\ImProgram\Python35 添加环境变量,将上述路径加入到path中 这样cmd打开命令窗口,输入python就能看到调用成功 ...
- [BZOJ1634][Usaco2007 Jan]Protecting the Flowers 护花 贪心
1634: [Usaco2007 Jan]Protecting the Flowers 护花 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 885 So ...
- JDK7集合框架源码阅读(一) ArrayList
基于版本jdk1.7.0_80 java.util.ArrayList 代码如下 /* * Copyright (c) 1997, 2013, Oracle and/or its affiliates ...
- react 使用antd的TreeSelect树选择组件实现多个树选择循环
需求说明,一个帐号角色可以设置管理多个项目的菜单权限 且菜单接口每次只能查询特定项目的菜单数据[无法查全部] 开发思路: 1,获取项目接口数组,得到项目数据 2,循环项目数据,以此为参数递归查询菜单数 ...
- #420 Div2 D
#420 Div2 D 题意 给出一个方格矩阵,其中存在亮着的方格,只能在亮着的方格上行走,可以在初始亮的方格上花费一枚硬币临时点亮任意一行或一列,地图上同一时间只能存在一个这样的行或列,问走到终点最 ...
- POJ 2763 Housewife Wind(树链剖分)(线段树单点修改)
Housewife Wind Time Limit: 4000MS Memory Limit: 65536K Total Submissions: 10378 Accepted: 2886 D ...
- jsp登陆
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"% ...