Java常见面试题汇总-----------数据库(数据库锁、数据库存储过程)

本文深入探讨了数据库的锁机制,包括共享锁和排他锁的类型,以及MySQL中锁的粒度。同时讲解了乐观锁与悲观锁的概念及其应用场景。此外,还介绍了数据库存储过程的基本概念、优点,以及如何定义和调用存储过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

57、数据库的锁

  锁是一种并发控制技术,锁是用来在多个用户同时访问同一个数据的时候保护数据的。

57.1、有 2 种基本的锁类型

  共享(S)锁: 多个事务可封锁一个共享页;任何事务都不能修改该页;通常是该页被读取完毕,S锁立即被释放。在执行 select 语句的时候需要给操作对象(表或者一些记录)加上共享锁,但加锁之前需要检查是否有排他锁,如果没有,则可以加共享锁(一个对象上可以加 n 个共享锁 ),否则不行。共享锁通常在执行完 select 语句之后被释放,当然也有可能是在事务结束(包括正常结束和异常结束)的时候被释放,主要取决于数据库所设置的事务隔离级别。

  排它(X)锁: 仅允许一个事务封锁此页;其他任何事务必须等到 X 锁被释放才能对该页进行访问;X 锁一直到事务结束才能被释放。执行 insert、update、delete 语句的时候需要给操作的对象加排他锁,在加排他锁之前必须确认该对象上没有其他任何锁,一旦加上排他锁之后,就不能再给这个对象加其他任何锁。排他锁的释放通常是在事务结束的时候(当然也有例外,就是在数据库事务隔离级别被设置成 Read Uncommitted(读未提交数据)的时候,这种情况下排他锁会在执行完更新操作之后就释放,而不是在事务结束的时候)。

57.2、mysql 锁的粒度(即锁的级别)

  MySQL 各存储引擎使用了三种类型(级别)的锁定机制:行级锁定,页级锁定和表级锁定。
  1、表级锁, 直接锁定整张表,在你锁定期间,其它进程无法对该表进行写操作。如果你是写锁,则其它进程则读也不允许。特点:开销小,加锁快;不会出现死锁;锁定粒度最大,发生锁冲突的概率最高,并发度最低。
  MyISAM 存储引擎采用的是表级锁。
  有 2 种模式:表共享读锁和表独占写锁。加读锁的命令:lock table 表名 read;去掉锁的命令:unlock tables。
  支持并发插入:支持查询和插入操作并发进行(在表尾并发插入)。
  锁调度机制:写锁优先。一个进程请求某个 MyISAM 表的读锁,同时另一个进程也请求同一表的写锁,MySQL 如何处理呢?答案是写进程先获得锁。

  2、行级锁, 仅对指定的记录进行加锁,这样其它进程还是可以对同一个表中的其它记录进行操作。特点:开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高。
  InnoDB 存储引擎既支持行级锁,也支持表级锁,但默认情况下是采用行级锁。

  3、页级锁, 一次锁定相邻的一组记录。开销和加锁时间界于表锁和行锁之间;会出现死锁;锁定粒度界于表锁和行锁之间,并发度一般。

  最常用的处理多用户并发访问的方法是加锁。当一个用户锁住数据库中的某个对象时,其他用户就不能再访问该对象。加锁对并发访问的影响体现在锁的粒度上。比如,(表锁)放在一个表上的锁限制对整个表的并发访问;(页锁)放在数据页上的锁限制了对整个数据页的访问;(行锁)放在行上的锁只限制对该行的并发访问。

57.3、按锁的机制分:有悲观锁和乐观锁

  悲观锁 ,锁如其名,他对世界是悲观的,他认为别人访问正在改变的数据的概率是很高的,所以从数据开始更改时就将数据锁住,直到更改完成才释放。
  一个典型的倚赖数据库的悲观锁调用:
  select * from account where name=”Erica” for update
  这条 sql 语句锁定了 account 表中所有符合检索条件(name=”Erica”)的记录。 本次事务提交之前(事务提交时会释放事务过程中的锁),外界无法修改这些记录。该语句用来锁定特定的行(如果有 where 子句,就是满足 where条件的那些行)。当这些行被锁定后,其他会话可以选择这些行,但不能更改或删除这些行,直到该语句的事务被 commit 语句或 rollback 语句结束为止。需要注意的是,select …for update 要放到 mysql的事务中,即 begin 和commit 中,否则不起作用。
  悲观锁可能会造成加锁的时间很长,并发性不好,特别是长事务,影响系统的整体性能。
  悲观锁的实现方式:
  悲观锁,也是基于数据库的锁机制实现。 传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁。

  乐观锁 ,他对世界比较乐观,认为别人访问正在改变的数据的概率是很低的,所以直到修改完成,准备提交所做的修改到数据库的时候才会将数据锁住, 当你读取以及改变该对象时并不加锁,完成更改后释放。乐观锁不能解决脏读的问题。
  乐观锁加锁的时间要比悲观锁短,大大提升了大并发量下的系统整体性能表现。
  乐观锁的实现方式:
  1、大多是基于数据版本(Version )记录机制实现, 需要为每一行数据增加一个版本标识(也就是每一行数据多一个字段 version),每次更新数据都要更新对应的版本号+1。
  工作原

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值