oracle的update加并发,关于update操作并发问题
在高并发的场景下,经常会遇到这种情况:
A请求过来,查询出来一条数据,进行update操作,与此同时B请求也在这个时候过来,对这条数据进行查询,并进行操作。此时就会出现B在A之后进行查询操作,但是实际B的数据却被A覆盖。
表名A,字段名为 number,如下的SQL语句:
甲操作 语句1:select num from store where id='1';
假设此时甲获取到 num= 99
乙操作 语句2:select num from store where id='1';
因为甲方还没有update操作,乙获也取到 num= 99
这时候A进行update操作
update store set num =${num} +1 where id='1';
这时候写入数据库的num即为100
此时B请求也发起了更新操作:
update store set num =${num} +1 where id='1';
这时候我们的预期本应该是101的,但是实际上B又在数据库写入了100
解决方案:
(1)引入一个版本号的概念,在表A中增加一个version字段
甲操作 语句1:select num,version from store where id='1';
假设此时甲获取到 num= 99 version =1
乙操作 语句2:select num,version from store where id='1';
因为甲方还没有update操作,乙获也取到 num= 99 version=1
这时候A进行update操作
update store set num =${num} +1 where id='1' and version = ${version};
这时候写入数据库的num即为100, version =2
此时B请求也发起了更新操作:
update store set num =${num} +1 where id='1' and version = ${version} ;
这时候发现条件version = 1不成立,因为上一步操作version已经为2了,所以update无法更新。
(2)解决方式:update A set number=number+1 where id=1; 语句直接处理
表名A,字段名为 number,如下的SQL语句:
语句1:update A set number=number+1 where id=1;
语句2:update A set number=number+2 where id=1;
假设这两条SQL语句同时被mysql执行,id=1的记录中number字段的原始值为99,那么是否有可能出现这种情况:
语句1和2因为同时执行,他们得到的number的值都是99,都是在10的基础上分别加1和2,导致最终number被更新为100或101,而不是102
这个其实就是 关系型数据库本身就需要解决的问题。首先,他们同时被MySQL执行,你的意思其实就是他们是并发执行的,而并发执行的事务在关系型数据库中是有专门的理论支持的- ACID,事务并行等理论,所有关系型数据库实现,包括Oracle, MySQL都需要遵循这个原理。
简单一点理解就是锁的原理。这个时候第一个update会持有id=1这行记录的 排它锁,第二个update需要持有这个记录的排它锁的才能对他进行修改,正常的话, 第二个update会阻塞,直到第一个update提交成功,他才会获得这个锁,从而对数据进行修改。
也就是说,按照关系型数据库的理论,这两个update都成功的话,id=1的number一定会被修改成22。如果不是22, 那就是数据库实现的一个严重的bug。
oracle的update加并发,关于update操作并发问题相关推荐
- oracle blob update,Oracle数据库中对BLOB数据的操作问题
[TechTarget中国原创]问:请问在Oracle数据库中,如何插入并检索二进制大对象数据(BLOB)? 答:我建议在处理大对象数据之前,先阅读一下"Oracle应用开发者指南" ...
- select for update加了行锁还是表锁?
前言 大家,我是田螺. 最近在开发需求的时候,用到了select......for update.在代码评审的时候,一位同事说 ,唯一索引+一个非索引字段,是否可能会锁全表呢?本文田螺哥将通过9个实验 ...
- MYSQL中ON DUPLICATE KEY UPDATE对数据进行insertOrUpdate操作
本文来自:高爽|Coder,原文地址:[url]http://blog.csdn.net/ghsau/article/details/23557915[/url],转载请注明. 向数据库插入记录时,有 ...
- SAP CRM IBASE在ABAP update task中实现update和delete操作
本文介绍SAP CRM IBASE在ABAP update task中实现update和delete操作的原理. 要获取更多Jerry的原创文章,请关注公众号"汪子熙":
- Oracle 10g RAC 升级(CPU Update)之--升级CRS
Oracle 10g RAC 升级(CPU Update)之--升级CRS 系统环境: 操作系统:RedHat EL5 Cluster: Oracle CRS 10.2.0.1.0 Oracle: ...
- oracle的commit耗时长_ORACLE COMMIT操作的详解
通常对undo有一个误解,认为undo用于物理地恢复到执行语句或事务之前的样子,但实际上并非如此.数据库只是逻辑地恢复到原来的样子,所有修改都被逻辑地取消,但是数据结构以及数据库块本身在回滚后可能大不 ...
- java调用oracle删除,使用IDEA对Oracle数据库进行简单增删改查操作
1.1 java中的数据存储技术 在java中,数据库存取技术可分为如下几类: 1.jdbc直接访问数据库 2.jdo(java data object)是java对象持久化的新的规范,也是一个用于存 ...
- Oracle数据库的数据更新语句与视图操作示例(包含大部分常用语句)
Oracle数据库的数据更新语句与视图操作(包含大部分常用语句) 目标 本文用到的关系模式 语句示例 1.在创建的student, course, teacher, sc, tc表中用SQL语句完成以 ...
- linux 文件重新运行,Linux锐速启动,停止,以及重新加载配置等操作参数说明
使用serverSpeeder 服务进行锐速的启动,停止,以及重新加载配置等操作:各参数说明如下: service serverSpeeder start :启动锐速,加载加速模块:使用/server ...
- oracle首先创建三个表,oracle理论学习详解及各种简单操作例子(初学者必备)
oracle理论学习详解及各种简单操作例子(菜鸟必备) 1.数据库的发展过程 层次模型 -->网状模型 -->关系模型 -->对象关系模型 2.关于数据库的概念 DB:数据库(存储信 ...
最新文章
- 2021年大数据Hadoop(二十二):MapReduce的自定义分组
- isulad代替docker_云原生时代的华为新“引擎”:iSula | Linux 中国
- Python基础之:Python中的模块
- Spring Boot知识清单
- i2c hid 触摸板不能用_零基础学硬件(6):I2C总线的用处
- mysql转移数增删改查_MySql CURD操作(数据的增删改查)
- 17muduo_base库源码分析(八)
- Android 数据存储/访问 之 SharedPreferences(偏好设定)
- 【Oracle】Oracle错误编码大全
- [DiMP跟踪算法]代码学习笔记
- 苹果CMS插件安装使用下载苹果CMS插件集合
- 关于DSP系统时钟的一些理解
- Unity笔记-29-ARPG游戏项目-05-简易的战斗系统
- 不看你就亏了。。。。
- linux内核DCB子系统
- 【限时删除】一个惊艳的神器,可全网爬取各种资源..........
- 全局负载均衡GSLB
- 端口隔离是什么?为什么需要端口隔离、如何实现端口隔离?一文解惑
- PC_控制器_微程序控制器和硬布线控制器
- 厚涂简不简单?怎么入门厚涂
热门文章
- 五步完成Spring整合Mybatis的完整示例
- Java一键多值Map 之Guava Multimap 用法简介
- My97DatePicker时间控件和编辑器的调用
- Ubuntu18.04/16.04 安装glog
- python使用多线程(二)
- 【洛谷 1027】双重回文数
- Codeforces - 1191D - Tokitsukaze, CSL and Stone Game - 博弈论
- 网络攻防 第六周学习总结
- attachEvent中this指向(转)
- Oracle中常用的to_Char用法详解(有FMT的详细列表)