问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501
你好,欢迎来到懂视!登录注册
当前位置: 首页 - 正文

数据库为什么需要锁机制?有哪些锁机制

发布网友 发布时间:2022-04-24 04:08

我来回答

2个回答

懂视网 时间:2022-04-08 09:13

数据库是一个多用户使用的共享资源。当多个用户并发地存取数据时,在数据库中就会产生多个事务同时存取同一数据的情况。若对并发操作不加控制就可能会读取和存储不正确的数据,破坏数据库的一致性。

加锁是实现数据库并发控制的一个非常重要的技术。当事务在对某个数据对象进行操作前,先向系统发出请求,对其加锁。加锁后事务就对该数据对象有了一定的控制,在该事务释放锁之前,其他的事务不能对此数据对象进行更新操作。

【基本锁类型】

锁包括行级锁和表级锁

行级锁是一种排他锁,防止其他事务修改此行;在使用以下语句时,Oracle会自动应用行级锁:
INSERT、UPDATE、DELETE、SELECT … FOR UPDATE [OF columns] [WAIT n | NOWAIT];
SELECT … FOR UPDATE语句允许用户一次锁定多条记录进行更新
使用COMMIT或ROLLBACK语句释放锁

表级锁又分为5类:

行共享 (ROW SHARE) – 禁止排他锁定表
行排他(ROW EXCLUSIVE) – 禁止使用排他锁和共享锁
共享锁(SHARE) - 锁定表,对记录只读不写,多个用户可以同时在同一个表上应用此锁
共享行排他(SHARE ROW EXCLUSIVE) – 比共享锁更多的限制,禁止使用共享锁及更高的锁
排他(EXCLUSIVE) – 限制最强的表锁,仅允许其他用户查询该表的行。禁止修改和锁定表

【乐观锁与悲观锁】 

所谓悲观锁就是基于数据库机制实现的。比如在在使用select子句的时候加上for update,那么直到改子句的事务结束为止,任何应用都无法修改select出来的记录。

所谓乐观锁是基于应用的版本机制来实现的。一般会在表里面设计一个版本字段v(我一般会把这个字段设为timestamp)。一般的update场景是这样:

1 select a, v from tb where id=1;   

假设得到数据是:[‘xxx‘, 11111]

2 update tb set a=‘yyyy‘, v=systimestamp where v=11111; //注意, v一般不会在业务操作的时候修改

这要求每一次update操作都变更版本字段,否则还是要进程间的数据 还是会被相互覆盖。

乐观锁无法锁定其他应用对数据的操作。 

锁(locking) 

业务逻辑的实现过程中,往往需要保证数据访问的排他性。如在金融系统的日终结算 处理中,我们希望针对某个cut-off时间点的数据进行处理,而不希望在结算进行过程中 (可能是几秒种,也可能是几个小时),数据再发生变化。此时,我们就需要通过一些机制来保证这些数据在某个操作过程中不会被外界修改,这样的机制,在这里,也就是所谓 的“锁”,即给我们选定的目标数据上锁,使其无法被其他程序修改。 Hibernate支持两种锁机制:即通常所说的“悲观锁(Pessimistic Locking)” 和“乐观锁(Optimistic Locking)”。

【Hibernate中的悲观锁和乐观锁的实现】

一 :悲观锁(Pessimistic Locking) 

悲观锁,正如其名,它指的是对数据被外界(包括本系统当前的其他事务,以及来自外部系统的事务处理)修改持保守态度,因此,在整个数据处理过程中,将数据处于锁定 状态。悲观锁的实现,往往依靠数据库提供的锁机制(也只有数据库层提供的锁机制才能 真正保证数据访问的排他性,否则,即使在本系统中实现了加锁机制,也无法保证外部系 统不会修改数据)。 一个典型的倚赖数据库的悲观锁调用: select * from account where name=”Erica” for update 这条sql 语句锁定了account 表中所有符合检索条件(name=”Erica”)的记录。 本次事务提交之前(事务提交时会释放事务过程中的锁),外界无法修改这些记录。 Hibernate的悲观锁,也是基于数据库的锁机制实现。 下面的代码实现了对查询记录的加锁:

技术分享 String hqlStr = " from TUser as user where user.name=’Erica’ " ; 
技术分享Query query = session.createQuery(hqlStr); 
技术分享query.setLockMode( " user " ,LockMode.UPGRADE); // 加锁 
技术分享 List userList = query.list(); // 执行查询,

获取数据 query.setLockMode 对查询语句中特定别名所对应的记录进行加锁(我们为 TUser类指定了一个别名“user”),这里也就是对返回的所有user记录进行加锁。 观察运行期Hibernate生成的SQL语句:

技术分享 select tuser0_.id as id, tuser0_.name as name, tuser0_.group_id as group_id, tuser0_.user_type as user_type, tuser0_.sex as sex from t_user tuser0_ where (tuser0_.name = ’Erica’ ) for update

这里Hibernate通过使用数据库的for update子句实现了悲观锁机制。 Hibernate的加锁模式有: 
? LockMode.NONE : 无锁机制。 
? LockMode.WRITE :Hibernate在Insert和Update记录的时候会自动 获取。 
? LockMode.READ : Hibernate在读取记录的时候会自动获取。 

以上这三种锁机制一般由Hibernate内部使用,如Hibernate为了保证Update 过程中对象不会被外界修改,会在save方法实现中自动为目标对象加上WRITE锁。

? LockMode.UPGRADE :利用数据库的for update子句加锁。 
? LockMode. UPGRADE_NOWAIT :Oracle的特定实现,利用Oracle的for update nowait子句实现加锁。 

上面这两种锁机制是我们在应用层较为常用的,加锁一般通过以下方法实现: 
Criteria.setLockMode 
Query.setLockMode 
Session.lock 
注意,只有在查询开始之前(也就是Hiberate 生成SQL 之前)设定加锁,才会 真正通过数据库的锁机制进行加锁处理,否则,数据已经通过不包含for update 子句的Select SQL加载进来,所谓数据库加锁也就无从谈起。


二 :乐观锁(Optimistic Locking) 
相对悲观锁而言,乐观锁机制采取了更加宽松的加锁机制。悲观锁大多数情况下依 靠数据库的锁机制实现,以保证操作最大程度的独占性。但随之而来的就是数据库 性能的大量开销,特别是对长事务而言,这样的开销往往无法承受。 如一个金融系统,当某个操作员读取用户的数据,并在读出的用户数据的基础上进 行修改时(如更改用户帐户余额),如果采用悲观锁机制,也就意味着整个操作过 程中(从操作员读出数据、开始修改直至提交修改结果的全过程,甚至还包括操作 员中途去煮咖啡的时间),数据库记录始终处于加锁状态,可以想见,如果面对几 百上千个并发,这样的情况将导致怎样的后果。 乐观锁机制在一定程度上解决了这个问题。乐观锁 大多是基于数据版本 (Version)记录机制实现。何谓数据版本?即为数据增加一个版本标识,在基于 数据库表的版本解决方案中,一般是通过为数据库表增加一个“version”字段来 实现。 读取出数据时,将此版本号一同读出,之后更新时,对此版本号加一。此时,将提 交数据的版本数据与数据库表对应记录的当前版本信息进行比对,如果提交的数据 版本号大于数据库表当前版本号,则予以更新,否则认为是过期数据。 对于上面修改用户帐户信息的例子而言,假设 :

数据库中帐户信息表中有一个 version字段,当前值为1;而当前帐户余额字段(balance)为$100。 
1 :操作员A 此时将其读出(version=1),并从其帐户余额中扣除$50 ($100-$50)。 
2 : 在操作员A操作的过程中,操作员B也读入此用户信息(version=1),并 从其帐户余额中扣除$20($100-$20)。 
3: 操作员A完成了修改工作,将数据版本号加一(version=2),连同帐户扣 除后余额(balance=$50),提交至数据库更新,此时由于提交数据版本大 于数据库记录当前版本,数据被更新,数据库记录version更新为2。 
4: 操作员B完成了操作,也将版本号加一(version=2)试图向数据库提交数 据(balance=$80),但此时比对数据库记录版本时发现,操作员B提交的 数据版本号为2,数据库记录当前版本也为2,不满足“提交版本必须大于记 录当前版本才能执行更新“的乐观锁策略,因此,操作员B 的提交被驳回。 这样,就避免了操作员B 用基于version=1 的旧数据修改的结果覆盖操作 员A的操作结果的可能。 

从上面的例子可以看出,乐观锁机制避免了长事务中的数据库加锁开销(操作员A 和操作员B操作过程中,都没有对数据库数据加锁),大大提升了大并发量下的系 统整体性能表现。 需要注意的是,乐观锁机制往往基于系统中的数据存储逻辑,因此也具备一定的局 限性,如在上例中,由于乐观锁机制是在我们的系统中实现,来自外部系统的用户 余额更新操作不受我们系统的控制,因此可能会造成脏数据被更新到数据库中。在 系统设计阶段,我们应该充分考虑到这些情况出现的可能性,并进行相应调整(如 将乐观锁策略在数据库存储过程中实现,对外只开放基于此存储过程的数据更新途 径,而不是将数据库表直接对外公开)。 Hibernate 在其数据访问引擎中内置了乐观锁实现。如果不用考虑外部系统对数 据库的更新操作,利用Hibernate提供的透明化乐观锁实现,将大大提升我们的 生产力。 Hibernate中可以通过class描述符的optimistic-lock属性结合version 描述符指定。 
现在,我们为之前示例中的TUser加上乐观锁机制。

1. 首先为TUser的class描述符添加optimistic-lock属性:

技术分享 < hibernate - mapping > 
技术分享  < class 
技术分享 name = " org.hibernate.sample.TUser " 
技术分享 table = " t_user " 
技术分享 dynamic - update = " true " 
技术分享 dynamic - insert = " true " 
技术分享 optimistic - lock = " version " 
技术分享  > 
技术分享 …… 
技术分享  </ class > 
技术分享  </ hibernate - mapping >

optimistic-lock属性有如下可选取值: 
? none 无乐观锁 
? version 通过版本机制实现乐观锁 
? dirty 通过检查发生变动过的属性实现乐观锁 
? all 通过检查所有属性实现乐

数据库锁技术

标签:

热心网友 时间:2022-04-08 06:21

数据库锁的产生原因:

数据库和操作系统一样,是一个多用户使用的共享资源。当多个用户并发地存取数据 时,在数据库中就会产生多个事务同时存取同一数据的情况。若对并发操作不加控制就可能会读取和存储不正确的数据,破坏数据库的一致性。加锁是实现数据库并 发控制的一个非常重要的技术。在实际应用中经常会遇到的与锁相关的异常情况,当两个事务需要一组有冲突的锁,而不能将事务继续下去的话,就会出现死锁,严 重影响应用的正常执行。

在数据库中有两种基本的锁类型:排它锁(Exclusive Locks,即X锁)和共享锁(Share Locks,即S锁)。当数据对象被加上排它锁时,其他的事务不能对它读取和修改。加了共享锁的数据对象可以被其他事务读取,但不能修改。数据库利用这两 种基本的锁类型来对数据库的事务进行并发控制。
怎么理解数据库的锁? 一般锁分别哪几种?

在数据库多用户并发环境中,理解锁机制至关重要,因为这有助于维护数据一致性。数据库锁是并发控制的关键技术,通过在操作数据前对数据对象加锁,确保事务之间的操作互不干扰。主要有两种基本类型的锁:排它锁(X锁)和共享锁(S锁)。X锁禁止其他事务读取和修改数据,而S锁则允许读取但禁止修改。Oracl...

数据恢复要留意哪些方面?

要找正规专业的公司,行业口碑也比较重要。以上回答如果还觉得不够详细,可以来咨询下壹寰(深圳)科技文化有限公司。91数据恢复是壹寰(深圳)科技文化有限公司旗下专业数据恢复品牌,91数据恢复专注于勒索病毒数据恢复、勒索病毒数据修复、数据库...

数据库为什么需要锁机制

锁是为了各个用户能够准确的操作数据而存在的。

数据库死锁死锁原因

数据库死锁问题主要源于四个条件的结合:互斥性、占有与等待、不可抢占性以及循环等待。当这些条件同时满足时,两个或多个并发事务将互相等待对方释放资源,导致系统停滞,即死锁状态。死锁的预防与解决策略需要从系统设计、进程调度、资源分配算法等多个层面综合考虑。为避免死锁,设计系统时需确保资源的合理...

MySQL数据库的两段锁机制及其应用mysql两段锁

两段锁机制的基本原理是在事务过程中对数据进行加锁,以控制数据的访问权限。其中,第一段锁是指事务启动后,将需要访问的数据行加上锁,确保该数据行在事务提交前不会被其他事务修改。而第二段锁是指事务提交前,需要将所有锁释放。有两种类型的锁:共享锁和排他锁。共享锁表示该数据可以被多个事务同...

数据库表级锁行级锁分别是什么?

数据库的两种主要锁机制是表级锁和行级锁,这在MySQL中体现得尤为明显,尤其是InnoDB引擎的灵活性。表级锁在MyISAM和MEMORY存储引擎中使用,而InnoDB则支持两者。表级锁的特点是操作时锁定整张表,加锁快但并发度低,易于产生锁冲突。它适用于读操作较多且并发要求不高的场景,但写操作可能会阻塞大量读...

数据库中的封锁机制是什么的主要方法

1. 并发控制的核心在于封锁机制,它是确保事务在多用户环境中正确执行的关键技术。2. 封锁是事务对数据资源进行访问控制的一种机制,包括三个基本步骤:首先是请求加锁,事务在开始操作前向系统提出对数据的锁定请求;其次是锁的授予,当系统确认资源可用时,事务获得对数据的控制权;最后是锁的释放,事务...

数据库中的封锁机制是什么的主要方法

封锁机制是并发控制的主要手段。封锁是使事务对它要操作的数据有一定的控制能力。封锁具有3个环节:第一个环节是申请加锁,即事务在操作前要对它欲使用的数据提出加锁请求;第二个环节是获得锁,即当条件成熟时,系统允许事务对数据加锁,从而事务获得数据的控制权;第三个环节是释放锁,即完成操作后...

MySQL数据库的三级封锁实现原理简述mysql三级封锁

在使用MySQL数据库的三级封锁机制时,我们需要根据具体的应用场景来选择相应的锁级别。一般来说,我们可以选择共享锁或者排它锁来实现事务的锁机制。下面是使用MySQL数据库的共享锁和排它锁的代码示例:使用共享锁:begin;select * from table where id=’1′ lock in share mode;//读取...

MySQL系列(六)— MySQL锁精讲

锁的分类包括:乐观锁和悲观锁;根据数据操作粒度,有全局锁、表锁、页锁、间隙锁和行锁;根据数据库操作类型,有读锁、写锁和意向锁。全局锁锁定整个数据库实例,使实例处于只读状态,常用于全库逻辑备份。表锁锁定整个表,开销小,加锁快,适用于整表数据迁移。行锁锁定一行数据,开销大,加锁慢,...

MySQL锁分析之死锁、元数据锁、事务锁

MySQL锁机制解析:死锁、元数据锁与事务锁详解在MySQL数据库中,锁机制是确保数据一致性的重要手段。本文将带你了解死锁、元数据锁和事务锁的原理、创建实例和分析方法。死锁示例与分析首先,通过实例演示死锁的产生。在一个MySQL测试环境中,两个连接分别执行如下操作:连接1:连接2:执行SHOW ENGINE INNODB ...

声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。
E-MAIL:11247931@qq.com
网线插座如何安装方法 无须的近义词和反义词是什么_无须是什么意思? PPT文件视图有几个? 求助很急,这个系列的图片叫什么 这个系列的韩国插画叫什么? 这种是什么类型的插画? 这个系列的图片,叫什么? 仙侠奇缘之花千骨广播剧 发到 852436014@qq.com 谢了~~ 斗罗大陆四大女主的辈分 吕薇个人荣誉 有好的清晰车载MP4视频下载网站的 车载MP4下载什么格式的电影 什么播放下载车载mp4视频下载 车载MV视频到哪里下载的好?什么格式最好? 车载MP4视频 怎么下载 最好有信得过的网站 求解 请问怎么下载车载视频 车载视频mp4格式怎么播放不了 有什么方法能除螨虫? 各位朋友请问车载视频mp4格式怎么下载? 怎样下载MP4到车载器上 杀螨虫最有效的方法? 各位朋友请问车载视频mp4格式怎么下载 显示器的插头插在哪里 家里到处都是螨虫,有什么方法,可以帮你有效防螨除螨? 不是可以组词吗? 电脑显示屏插头该往哪插 旧联想电脑显示器电源线插头在其他电脑主机上没地方插咋办? oppo手机在哪里下载东西 oppO手机怎么下载APPStore? oppo手机下载软件在哪里 数据库为什么需要锁机制 数据库封锁机制是什么 mysql数据库truncate的锁机制是什么? “sql”加锁机制是什么? oracle数据库锁机制怎么写 SQL Server数据库表锁定原理以及如何解除表的锁定 sql数据库里锁是什么 关于Sqlserver数据库 锁机制的小疑问,下种情况是否需要加入锁机制 数据库 对某条记录实现锁机制 SQL Server数据库表锁定原理以及如何解除锁定 greenplum数据库的死锁机制怎么解决 关于数据库死锁的问题,求助 备考GRE,需要准备哪些资料 gre考试需要带什么? GRE考试一般要准备多久? GRE要考试什么? 考GRE需要哪些准备? 梦到玻璃碎了? 成都哪里有便宜的电脑液晶显示器? 成都二手19寸电脑显示器多少钱?
  • 焦点

最新推荐

猜你喜欢

热门推荐