postgresql|数据库|SQL语句冲突的解决

news/2024/7/9 21:09:59 标签: 数据库, sql, postgresql, oracle

前言:

postgresql数据库是比较复杂的一个关系型数据库,而有些时候,即使是简单的插入更新操作也是有很多复杂的机制。

那么,什么是冲突?什么时候会遇到冲突(也就是冲突的常见场景)?如果有冲突我们应该怎么去解决?这些问题我想应该是在此文章中详细说明的。

一,

什么是冲突?

复杂点的说法:数据库的冲突主要是指并发事务对同一数据的读写操作和写写操作。例如,当多个用户同时尝试修改同一行数据时,可能会发生冲突。这种冲突可能会导致数据不一致或数据损坏。

解决这种并发冲突的方法有多种。其中一种是通过锁定整个行数据或整个表数据来防止并发错误,这分别被称为行锁和表锁。行锁的开销小,加锁快,但出现死锁的概率较高;表锁的锁定力度大,发生锁冲突的概率较低,但会导致并发度最低。

另外,乐观并发控制是另一种解决冲突的方法,它假设并发冲突相对较少。与悲观方法(预先锁定数据,然后再进行修改)相反,乐观并发不会进行锁定,但如果数据自查询后发生更改,则会安排数据修改在保存时失败。此并发失败会报告给应用程序,应用程序会进行相应处理,例如可能会对新数据重试整个操作。(这些也就是面试DBA的时候常说的悲观锁,乐观锁这些)

简单来说,就

假设有一个名为"employees"的表,其中包含以下列:id、name、age和salary。现在有两个并发事务,它们都试图更新同一个员工的薪水。

事务1:

 

BEGIN; UPDATE employees SET salary = 5000 WHERE id = 1; COMMIT;

事务2:

 

BEGIN; UPDATE employees SET salary = 6000 WHERE id = 1; COMMIT;

在这个例子中,事务1将员工的薪水从4000更新为5000,而事务2也将员工的薪水从4000更新为6000。由于这两个操作是并发执行的,因此最终的结果将是员工的薪水被更新为6000,而不是预期的5000。这就是一个典型的PostgreSQL冲突示例。

我们在使用SQLinsert语句进行插入 操作 ,而目标表中存在这些数据将会导致这些insert 的SQL语句失败, 这个时候,我们就可以说有冲突现象发生了。

例如:

二,

冲突在什么时候出现?

很简单,多用户同一时间执行同一个插入的SQL语句的时候,还一种情形是增量迁移,增量同步数据的时候,第二种情形应该是比较常见的。

三,

冲突的解决

  1. 悲观锁(Pessimistic Locking):悲观锁是一种并发控制策略,它假设多个事务在没有冲突的情况下同时执行的可能性很小,因此在每个事务开始时就会锁定数据行或表,直到事务完成并释放锁。这种机制可以有效地避免冲突,但会导致并发性能下降。

  2. 乐观锁(Optimistic Locking):乐观锁是一种并发控制策略,它假设多个事务在没有冲突的情况下同时执行的可能性很大,只有在提交时才会检查是否存在冲突。如果存在冲突,则事务会被回滚并重新尝试。这种机制可以提高并发性能,但需要额外的逻辑来处理冲突。

  3. 时间戳(Timestamping):时间戳是一种简单的并发控制策略,它在每个记录中添加一个时间戳字段,用于记录该记录的最后修改时间。当更新记录时,比较当前时间戳和记录中的时间戳是否一致,如果不一致则说明有其他事务已经修改了该记录,需要重新执行更新操作。

  4. 分布式锁(Distributed Locking):分布式锁是一种在分布式系统中解决并发冲突的机制,它可以确保只有一个节点能够访问共享资源。常见的实现方式包括基于Redis、Zookeeper等中间件实现的分布式锁。

  5. 重试机制(Retry Mechanism):重试机制是一种常见的解决冲突的方法,当某个操作失败时,会进行多次重试,直到成功为止。这种方法适用于一些非关键性操作,但对于关键性操作可能会导致数据不一致等问题。

  6. 忽视冲突  适用于上面第二节说的增量更新同步,迁移数据库的操作

示例1:

忽视冲突

例如,两张表之间的同步,虽然形式上是全表同步,但希望实现的效果是增量同步,此时,我们需要在INSERT语句后面添加冲突指示:on conflict DO NOTHING; 这样有相同的数据时,检查到了冲突,忽略掉此条数据插入,保持原有数据不变。

INSERT INTO 表1名 SELECT * FROM 表2名 on conflict DO NOTHING;

示例2:

冲突后update更新(部分冲突更新)

---表示在向名为table_name的表中插入一条数据,
---其中包含两个字段:column1和column2。
---如果表中已经存在具有相同column1值的记录,
---则将该记录的column2字段更新为新插入记录的column2值。

INSERT INTO table_name (column1, column2)
VALUES (value1, value2)
ON CONFLICT (column1) DO UPDATE SET column2 = EXCLUDED.column2;

 示例3:

冲突后,根据条件更新字段

INSERT INTO table_name (column1, column2)
VALUES (value1, value2)
ON CONFLICT (column1) DO UPDATE SET column2 = EXCLUDED.column2 WHERE column2 < EXCLUDED.column2;

示例4:

DO NOTHING RETURNING:在发生冲突时不执行任何操作,若不冲突返回插入的行。

INSERT INTO table_name (column1, column2)
VALUES (value1, value2)
ON CONFLICT (column1) DO NOTHING RETURNING *;

示例5:

DO UPDATE SET ... WHERE ... RETURNING:在发生冲突时执行更新操作,并根据条件进行更新,并返回更新的行 

INSERT INTO table_name (column1, column2)
VALUES (value1, value2)
ON CONFLICT (column1) DO UPDATE SET column2 = EXCLUDED.column2 WHERE column2 < EXCLUDED.column2 RETURNING *;

未完待续!!!


http://www.niftyadmin.cn/n/5142269.html

相关文章

行情分析——加密货币市场大盘走势(11.1)

大饼短期内处于震荡&#xff0c;目前在吸血山寨。对于做中长线的也是可以秉持“做多大饼&#xff0c;做空山寨“的原则。目前大饼依然保持逢低做多即可&#xff0c;短期内依然不容易下跌。稳健的朋友&#xff0c;大家可以不做大饼。 以太目前也是处在震荡向上过程&#xff0c;以…

k8s.1.28.x空间预留,过期镜像删除

CPU和内存预留配置 使用 kubelet 的配置文件中指定 kube-reserved 字段 在 kubeadm init 命令的参数文件中指定 kube-reserved 字段 使用 kubelet 的配置文件在 kubelet 的配置文件中&#xff0c;可以通过指定 kube-reserved 字段来预留节点的空间。kube-reserved 字段是一个对…

SortableJS:vuedraggable实现元素拖放排序

文档&#xff1a;https://sortablejs.github.io/Sortable/github&#xff1a;https://github.com/SortableJS/SortableVue2: https://github.com/SortableJS/Vue.DraggableVue3: https://github.com/SortableJS/vue.draggable.nextnpm https://www.npmjs.com/package/vuedragga…

一大早被用户吵醒!微信小程序用不了了【微信小程序用户隐私保护】

一、一开始事情是这样事儿的 几周前用户收到提示的时候发给我看&#xff0c;我没有当回事&#xff08;ps内心:能腾一腾就腾一腾&#xff0c;没时间搞&#xff09; 几周后&#xff0c;突然的一大早用户就给我发微信说微信小程序登录不进去&#xff0c;学生没法正常使用学习&am…

UWB 技术在机器人和移动领域的应用题】

多年来&#xff0c;机器人生态系统不断增长&#xff0c;不同的应用程序也在不断增长。如今&#xff0c;机器人出现在许多不同的领域&#xff0c;例如私人家庭、商业场所、仓库和医疗场所。他们要么自主工作&#xff0c;要么与我们并肩工作&#xff0c;帮助我们完成任务。 根据…

Go语言并发控制:原理与实践

摘要&#xff1a; 本文将深入探讨Go语言的并发控制机制&#xff0c;包括goroutine、channel和sync等关键概念。我们将通过理论阐述和案例分析&#xff0c;揭示Go语言在并发编程中的优势和挑战&#xff0c;并介绍几种常见的并发控制策略。通过本文的学习&#xff0c;你将掌握Go…

二十二、Arcpy批量波段组合——结合Landat数据城市建成区提取

一、前言 其实波段组合和GIS中栅格计算有点类似,实质上就是对每个像素点对应的DN值进行数学计算,也就是可以进行运算表达式是三个或多个变量相加、相减……每一个变量对应于一个图像数据,对这三个或多个图像数据求值并输出结果图像。 二、具体操作 1、实验具体目标 将202…

transformers-Generation with LLMs

https://huggingface.co/docs/transformers/main/en/llm_tutorialhttps://huggingface.co/docs/transformers/main/en/llm_tutorial停止条件是由模型决定的&#xff0c;模型应该能够学习何时输出一个序列结束&#xff08;EOS&#xff09;标记。如果不是这种情况&#xff0c;则在…