并发与锁定

当多用户同一时刻访问相同的数据库资源时,将产生并发。并发极易破坏数据的一致性。锁定是处理并发的重要手段,用户在修改某一资源前,必须首先获得资源的修改权。而这种修改权具有排他性。

并发与锁定举例

更新表中记录首先获得该记录上的排它锁,从而防止两个进程同时修改同一条记录。

update students set student_name='张军' where student_id=16;
当用户更新记录时,将获得在该记录上的排它锁,只有事务结束,该锁定才会被释放。

死锁

死锁是指2个进程都尝试获取对方已获得的锁,从而导致双方互相等待。如果没有对应的处理措施,那么这种状态将一直持续下去。

当死锁发生时,Oracle总是自动检测死锁,并强制其中一个事务放弃原任务,这样,只保证其中一个事务能够正常完成。

悲观锁与乐观锁

锁分为2种:悲观锁和乐观锁。

悲观锁是指,当前进程在每次更新数据时,总是假设有其他进程正在锁定同一资源;

乐观锁则假定不存在锁定请求资源的其他进程。

Oracle中的悲观锁定

锁定表中记录可以利用for Update
select * from students where student_id=1 for update
在锁定时利用nowait,指定数据库不必等待,直接放弃锁定操作
select * from students where student_id=1 for update nowait
此时会报错,表示资源忙,锁定失败,如果不加nowait,该进程会一直等待第一个进程释放资源。

Oracle中的乐观锁定

A用户和B用户同时修改一个记录时

更新数据时的并发问题的解决办法为将表的所有列作为过滤条件。

update students set student_age=20 where student_id=1 and student_name='金瑞' and student_age=26 and status='cxl'
由于B用户已经修改了数据。A用户用原来的数据作为条件更新时,就匹配不到这条记录,所以A会更新失败。

除了利用所有列作为过滤条件外,可以利用version列实现相同功能

1.给表students中新增列version,默认值为0
alter table students and version number default 0;
2.更新时,将version列加入过滤条件
update students set student_age=19 where student_id=1 and version=0;
3.再执行update students set version=version+1 where student_id=1 and version=0;

第三种方式是利用时间戳列来代替version列,并将时间戳加入过滤条件、每次更新成功,利用当前时间戳来更新时间戳列

锁定转换

一个数据库中,某一时刻可能存在着多个锁,而且,当数据库状态发生改变时,锁的数量也可能随之膨胀。在sql server中,利用链表来维护和管理锁。当一个事务中的锁的数量达到升级门限时,sql进行锁定升级,而Oracle则完全摒弃了这种做法。

一般数据库中的锁定升级

sql server 所能管理的锁的数量是有限制的。当某个表上锁定超过了一定数量,sql server通过提升锁的粒度来减少锁定的数量。例如,students表上可能有多个行级锁,当锁的数量达到一定极限时,这些行级锁将被转换为一个表级锁。通过这种方式,sql server将数据库的锁的数量维持在某个水平之下。

锁定升级的好处是可以很容易的维护锁的数量,但是由于一个独占锁在同一时刻只能为一个事务所拥有,因此,锁定升级往往以损失事务并发为代价。

Oracle中的锁定转换

Oracle的锁定信息是以属性的形式,直接存储于数据款和数据行(表记录)之上。换句话说,Oracle数据的存储结构已经为是否锁定、锁的类型,以及被哪个事务锁定等信息预留了存储空间。无论一条记录是否被锁定,都会有相应的标志位进行标识。每当一个事务尝试在某些数据上加锁时,首先要访问数据本身的标志位,以验证是否允许锁定。

这样,在一个事务中,为1条记录和为100天松记录添加行级锁,Oracle维护的空间及开销是大致相同的。事实上,Oracle只是添加一个锁,并更新被锁定数据本身的属性信息。因为没有锁列表的存在,Oracle也不必进行锁定升级。

锁定转换的意义在于,对于一个dml操作,如果需要进行数据锁定,Oracle总是尽量使锁的独占性最低。当真正需要进行数据操作时,才会将独占性提高。也就是说,Oracle所创建的锁总是保持着‘够用即可’的状态,以尽量减少对其他事务请求同一资源时的影响。

悲观锁适合并发数不大的情况下。

乐观锁适合并发较高的情况。

Oracle并发控制的更多相关文章

  1. Oracle并发控制、事务管理学习笔记

    (a)基本概念 锁的2种最基本.最简单的类型:排他锁(eXclusive lock,即X锁).共享锁(Share lock,即S锁). 不同级别的锁定协议及其作用: 申请的锁 及其作用 锁定协议 修改 ...

  2. oracle的乐观锁和悲观锁

    一.问题引出 1. 假设当当网上用户下单买了本书,这时数据库中有条订单号为001的订单,其中有个status字段是’有效’,表示该订单是有效的: 2. 后台管理人员查询到这条001的订单,并且看到状态 ...

  3. (转)DB2和 Oracle的并发控制(锁)比较

    DB2和 Oracle的并发控制(锁)比较 牛 新庄2005 年 12 月 26 日发布 原文:https://www.ibm.com/developerworks/cn/data/library/t ...

  4. Oracle编程入门经典 第12章 事务处理和并发控制

    目录 12.1          什么是事务处理... 1 12.2          事务处理控制语句... 1 12.2.1       COMMIT处理... 2 12.2.2       RO ...

  5. Oracle数据库—— 事务处理与并发控制

    一.涉及内容 1.理解事务的概念和几个特性. 2.熟练掌握事务管理命令的使用. 3.理解并发操作的概念和数据库锁的类型. 二.具体操作 (12.5 实验) 1. 分析以下代码,说出代码中的哪些部分体现 ...

  6. 【Oracle 集群】ORACLE DATABASE 11G RAC 知识图文详细教程之缓存融合技术和主要后台进程(四)

    缓存融合技术和主要后台进程(四) 概述:写下本文档的初衷和动力,来源于上篇的<oracle基本操作手册>.oracle基本操作手册是作者研一假期对oracle基础知识学习的汇总.然后形成体 ...

  7. Oracle学习笔记七 锁

    锁的概念 锁是数据库用来控制共享资源并发访问的机制. 锁用于保护正在被修改的数据 直到提交或回滚了事务之后,其他用户才可以更新数据 对数据的并发控制,保证一致性.完整性.

  8. SQLite剖析之锁和并发控制

    在SQLite中,锁和并发控制机制都是由pager.c模块负责处理的,用于实现ACID(Atomic.Consistent.Isolated和Durable)特性.在含有数据修改的事务中,该模块将确保 ...

  9. MVCC PostgreSQL实现事务和多版本并发控制的精华

    原创文章,同步发自作者个人博客,http://www.jasongj.com/sql/mvcc/ PostgreSQL针对ACID的实现机制 事务的实现原理可以解读为RDBMS采取何种技术确保事务的A ...

  10. Oracle Latch的学习【原创】

    Latch详解 - MaxChou 本文以学习为目的,大部分内容来自网络转载. 什么是Latch 串行化 数据库系统本身是一个多用户并发处理系统,在同一个时间点上,可能会有多个用户同时操作数据库.多个 ...

随机推荐

  1. Redis + Springboot + Mybatis插入数据时redis中uid为空

    原因 插入时数据库的id会自增,bean对象无法自动生成uid 解决 在mybatis的插入方法中添加useGeneratedKeys属性 useGeneratedKeys 对于支持自动生成记录主键的 ...

  2. mybatis——分页插件PageHelper的使用

    项目开发中涉及列表查询时,经常会需要对查询结果进行分页处理:常用的一个插件--PageHelper,是国内非常优秀的一款开源的mybatis分页插件,它支持基本主流与常用的数据库,一致支持mysql. ...

  3. 基于CARLA与PyTorch的自动驾驶仿真系统全栈开发指南

    引言:自动驾驶仿真的价值与技术栈选择 自动驾驶作为AI领域最具挑战性的研究方向之一,其开发流程需要经历"仿真测试-闭环验证-实车部署"的完整链路.其中,高保真仿真平台为算法迭代提供 ...

  4. 开发 MCP Proxy(代理)也可以用 Solon AI MCP 哟!

    MCP 有三种通讯方式: 通道 说明 备注 stdio 本地进程内通讯 现有 sse http 远程 http 通讯 现有 streamable http 远程 http 通讯 (MCP 官方刚通过决 ...

  5. python 处理word 分页符、分节符

    import docx doc1 =docx.Document(r"C:\Users\Administrator\Desktop\test.docx") doc1.paragrap ...

  6. 45分钟从零搭建私有MaaS平台和生产级的Qwen3模型服务

    今天凌晨,阿里通义团队正式发布了 Qwen3,涵盖六款 Dense 模型(0.6B.1.7B.4B.8B.14B.32B)和两款 MoE 模型(30B-A3B 和 235B-A22B).其中的旗舰模型 ...

  7. 在Ubuntu Server上安装Checkmk监控系统

    一.安装前准备 更新系统并安装依赖: sudo apt update && sudo apt upgrade -y sudo apt install -y wget apt-trans ...

  8. git提示:There is no tracking information for the current branch

    问题 使用git pull拉取远程分支代码的时候,提示: > There is no tracking information for the current branch. Please sp ...

  9. java如何启动时定义并初始化一个全局变量(内存中)

    前言 java如何启动时定义并初始化一个全局变量(内存中),项目启动时,通过读取配置文件来构建一个实体类对象,然后在之后可以直接使用,而不是每次使用都要进行构建 前置准备 实体类结构 package ...

  10. 「Log」2023.8.28 小记

    序幕 七点多到校,整理博客,开了一篇新做题记录. 整理一下学过知识点,准备阶段复习. 八点整开始打模拟赛,接下来算游记. T1 是个静态区间第 \(k\) 小板子,纯主席树被空间卡掉了,打了 \(60 ...