【为什么要锁】
  数据库是一个多用户使用的共享资源,比如一个用户表t_user,两个浏览器前面的人登录了同个一个账号,把电话号码改了。当多个用户并发地存取数据时,在数据库中就会产生多个事务同时存取同一数据的情况。若对并发操作不加控制就可能会读取和存储不正确的数据,破坏数据库的一致性(脏读,不可重复读,幻读等),可能产生死锁。为了解决这个问题,加锁是一个非常重要的技术,对实现数据库并发控制是一个好的方案。简单说,当一个执行sql语句的事务想要操作表记录之前,先向数据库发出请求,对你访问的记录集加锁,在这个事务释放这个锁之前,其他事务不能对这些数据进行更新操作。

【有哪些锁】
  锁包括行级锁、表级锁、悲观锁、乐观锁
  行级锁:一种它锁,防止另外事务修改此行;在使用以下语句时,Oracle会自动应用行级锁:INSERT、UPDATE、DELETE、SELECT … FOR UPDATE [OF columns] [WAIT n | NOWAIT];SELECT … FOR UPDATE语句允许用户一次锁定多条记录进行更新.使用commit或者rollback释放锁。MySql的innodb存储引擎默认是行级锁。特点:开锁大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高。适合于有大量按索引更新少量不同数据,同时又有并发查询的应用,如一些在线事务处理系统。
  表级锁:5种
  行共享 (ROW SHARE) – 禁止排他锁定表,与行排他类似,区别是别的事务还可以在此表上加任何排他锁。(除排他(exclusive)外)
  行排他(ROW EXCLUSIVE) – 禁止使用排他锁和共享锁,其他事务依然可以并发地对相同数据表执行查询,插入,更新,删除操作,或对表内数据行加锁的操作,但不能有其他的排他锁(自身是可以的,没发现有什么用)
  共享锁(SHARE) - 锁定表,对记录只读不写,多个用户可以同时在同一个表上应用此锁,在表没有被任何DML操作时,多个事务都可加锁,但只有在仅一个事务加锁的情况下只有此事务才能对表更新;当表已经被更新或者指定要更新时(select for update),任何事务都不能加此锁了。
  共享行排他(SHARE ROW EXCLUSIVE) – 比共享锁更多的限制,禁止使用共享锁及更高的锁,在表没有被任何DML操作时,只有一个事务可以加锁,可以更新,书上说别的事务可以使用select for update锁定选中的数据行,可是实验后没被验证。
  排他(EXCLUSIVE) – 限制最强的表锁,仅允许其他用户查询该表的行。禁止修改和锁定表

  行级锁和表级锁是根据锁的粒度来区分的,行记录,表都是资源,锁是作用在这些资源上的。如果粒度比较小(比如行级锁),可以增加系统的并发量但需要较大的系统开销,会影响到性能,出现死锁,,因为粒度小则操作的锁的数量会增加;如果作用在表上,粒度大,开销小,维护的锁少,不会出现死锁,但是并发是相当昂贵的,因为锁定了整个表就限制了其它事务对这个表中其他记录的访问。

  悲观锁:

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

 Query q=Session.createQuery("select  * from t_profit where amount>10000");q.setLockMode("Profit",LockMode.UPGRADE);//Profit是Profit类的别名List<Profit> ps=q.list();

  执行的sql:select ….from t_profit where amount>10000 for update.hibernate的悲观锁通过数据库的for update实现。

  LockMode.NONE:无锁机制;

  LockMode.WRITE:insert,update记录时自动获取悲观锁;

  LockMode.READ在读取时自动获取悲观锁;

  LockMode.UPGRADE:利用数据库的for update子句加锁;

  LockMode.UPGRADE_NOWAIT:oracle特定实现,用oracle的for update nowait子句加锁

  乐观锁:

  Optimistic Lock,和悲欢锁相反,事务每次去操作数据之前,都假设其他事务不会修改这些需要访问的数据 ,所以 在访问之前不要求上锁,只是在进行更新修改操作的时候判断一下在访问的期间有没有其他人修改数据 了。它适用于多读的应用类型,冲突真的发生比较少的时候就比较好,这样省去了开销的开销,可以提高吞吐量;但如果是真的经常要发生冲突的,那每次还要去判断进行retry,反倒降低的性能,这个时候悲欢锁比较好。数据库如果提供类似于write_condition机制的其实都是提供的乐观锁。
  它的实现大多是基于数据版本versin记录机制。举个例子:

  1.利润表t_profit中有一个 version字段,当前值为1;而总资产余额字段(balance)为$10000

  2.操作员A读出version=1,从总资产减除2000,10000-2000=8000.

  3.A还没操作结束,此时操作员B也读出version=1,总资产减除5000,10000-5000=5000.

  4.A操作完成,把version加1,修改为2,把总资产减2000后提交更新数据库,更新成功

  5.B操作了,也加version加1,修改为2,把总资产减5000后提交更新数据库,此时发现version已经为2了,如B修改后加1的version一样,不满足乐观锁策略:”提交的版本必有大于记录当前的版本才能执行”。因此B的操作请求被驳回,这样就避免了B就version=1的旧数据修改的结果覆盖了A操作的结果的可能。如没有乐观锁,那A减去2000后剩余8000,但B操作的时候是用10000-5000剩余5000的,如果B的提交成功,总资产余额就是5000,但实际情况应该是8000-5000=3000的。出现总资产表记录和实际支出不一致。

  Hibernate对乐观锁的实现:

<hibernate-mapping><class name="com.f.TProfit" table="t_profit" optimistic-lock="version"></class></hibernate-mapping>

数据库的锁机制理解和运用相关推荐

  1. 并发编程(四):也谈谈数据库的锁机制

    首先声明,本次文章基本上都是从其他人的文章中或者论坛的回复中整理而来.我把我认为的关键点提取出来供自己学习.所有的引用都附在文后,在这里也就不一一表谢了. 第二个声明,我对于Internel DB并没 ...

  2. 数据库的锁机制(悲观锁/乐观锁)

    在数据库的锁机制中介绍过,数据库管理系统(DBMS)中的并发控制的任务是确保在多个事务同时存取数据库中同一数据时不破坏事务的隔离性和统一性以及数据库的统一性. 乐观并发控制(乐观锁)和悲观并发控制(悲 ...

  3. 详解数据库的锁机制及原理

    详解数据库的锁机制及原理 1.数据库锁的分类 2.行锁 共享锁(读锁S锁) 排他锁(写锁X锁) 更新锁 3.意向锁(IX/IS锁) 4.锁机制解释数据库隔离级别 5.元数据锁(MDL锁) 6.间隙锁 ...

  4. 【转】数据库的锁机制

    数据库的读现象浅析中介绍过,在并发访问情况下,可能会出现脏读.不可重复读和幻读等读现象,为了应对这些问题,主流数据库都提供了锁机制,并引入了事务隔离级别的概念. 并发控制 在计算机科学,特别是程序设计 ...

  5. MySQL数据库:锁机制

    当数据库中多个事务并发存取同一数据的时候,若对并发操作不加控制就可能会读取和存储不正确的数据,破坏数据库的一致性.MySQL锁机制的基本工作原理就是,事务在修改数据库之前,需要先获得相应的锁,获得锁的 ...

  6. 数据库中锁机制的学习

           我们在做很多项目时都要涉及到数据库,特别是一些比较大型的web项目,更是有较大的并发处理,所以对数据库的操作有可能会产生死锁,对于数据库的死锁,一般数据库系统都会有一套机制去解锁,一般不 ...

  7. 1. 请简述mysql数据库的锁机制_【MySQL入门】之MySQL数据库的锁机制(二)

    上篇文章主要聊了全局锁和表锁,并详细分析MDL锁的作用以及可能带来的问题.今天我们主要来聊一聊Innodb存储引擎的行锁.MySQL的行锁是在引擎层由引擎自己实现的,并不是所有的引擎都支持行锁,MyI ...

  8. 【数据库】聊一下数据库的锁机制

    为什么需要锁 作为一个程序员,我们知道,后端系统无时无刻不在支撑用户请求,而如果所有的组件都是一个串行化执行的,在对同一个资源进行并发访问的时候,只能A执行完毕,B在执行.但是这样显然对于一个高并发. ...

  9. 幂等性概念及数据库乐观锁机制

最新文章

  1. Django的下载与基本命令
  2. 《预训练周刊》第22期:Fastformer:加法注意力就是你所需要的、用于蛋白建模的大规模预训练语言模型...
  3. LGDT/LIDT - 加载全局/中断描述符表格寄存器
  4. asin c语言中 返回值范围_asin()_C语言asin()详解:反正弦函数,求反正弦值
  5. 统计学习方法(九)EM算法及其推广
  6. c语言程序中必不可少的,C语言程序设计(第3章程序控制语句)2
  7. java get请求 数组,浅谈vue中get请求解决传输数据是数组格式的问题
  8. 行内元素、块级元素和行内块级元素
  9. 数学_一文搞懂极大似然估计
  10. 图形推理1000题pdf_公务员考试:遇到图形推理题就烦恼?5招教你练成最强大脑...
  11. 联想微型计算机安装Win7,联想一体机如何安装win7_联想一体机怎么使用u盘重装win7...
  12. 全球高效能人士给青年的50个忠告(上) --转载
  13. Java中涉及到和金钱有关的属性的类型
  14. 基于@Valid注解自定义参数校验
  15. python计算方差的置信区间_python计算置信区间
  16. python debugger extension_Pykd——Python extension for WinDbg
  17. 复数辐角主值个人理解
  18. C语言---集合---合取-析取-异或-条件语句-双条件语句
  19. C语言实现:任意进制转换
  20. java jms 框架_Apache RocketMQ之JMS基本概念及使用

热门文章

  1. 计算机专业在广东省的录取分数线,深圳大学广东本科批稳居广东高校前4!2019各省录取分数线发布!...
  2. Apk脱壳圣战之---脱掉“梆梆加固”的保护壳
  3. 羊车门问题的python代码_作业:羊车门问题
  4. WeUI实例(官方)
  5. 如何适配处理iphoneX底部的横条 ?(转)
  6. 激光条纹中心提取——ZhangSuen法python
  7. HEVC学习(二十八) —— 量化之二
  8. Sorry, The number you dialed is power off.
  9. C语言进阶 之 字符串函数(4)
  10. xxlJob定时任务,文章的上下架