数据库的锁&事务

锁的分类

1. 按照锁的粒度分:

表锁 行锁

2. 锁的类型分:

		共享锁:也叫做share锁/S锁 特点:可以给表加,也可以给行数据加,其特点为: 给目标数据加上share锁之后允许其他事务继续对该数 据加share锁,不允许其他事务对该数据加排它锁;通常读取数据时使用 
		排他锁/独占锁:也叫X锁 特点:给数据加排它锁,不允许其他事务继续给该数据加排它锁,同时不允许其他事务给该行数据加共享 锁,适用于写操作 

在数据库中,经常执行读写操作为:
select…
insert…
delete…
pdate…
增删改操作默认给操作的行数据加排它锁
select操作默认不加任何锁

如何在查询时加共享锁/排它锁
select …lock in share mode; //查询加共享锁
select…for update; //查询加排它锁

select…from …where like ‘’ --表锁

mysql的存储引擎:
mysql5.5开始存储引擎变成InnoDB,特点:支持行锁

悲观锁和乐观锁

是两种思想

悲观锁:

当多事务/多线程并发执行时,事务总是悲观的认为,在自己访问数据期间,其他事务一定会并发执行,此时会产生线程 安全问题,所以为了保证线程安全,这个事务在访问数据时,立即给数据加锁,从而保证线程安全. 特点:可以保证线程安全,但是并发执行效率低下 
synchronized 排它锁都是悲观锁的应用

乐观锁:

在多线程/多事务并发执行中,某个事务总是乐观的认为,在自己执行期间,没有其他事务与之并发,认为不会产生线程 安全问题,所以不会给数据加锁;但是确实存在其他事务与之并发执行的情况,确实存在线程安全问题,为了保证线程 安全,通过版本号机制或CAS来保证线程安全.
 CAS:compare and swap 比较并交换

事务

什么是事务

事务是数据库中执行操作的最小执行单元,不可再分,要么全都执行成功,要么全都执行失败。

事务的四大特性

原子性  	一致性		 隔离性 		持久性

数据库中事务自动提交默认开启

查看事务的自动提交是否开启: 
show variables like 'autocommit' 
			on off
如何关闭事务自动提交: 
set autocommit=off;
事务管理: 
	开启事务: `begin` 
	提交事务: `commit` 
	回滚事务: `rollback`

对数据库的增删改操作默认开启事务,而select不涉及事务

当业务方法涉及到多步增删改操作时,且想要他们保证要成功全成功,但凡有一个操作失败,则整个操作应该全部失 败,此时就应该为这个业务方法开启事务管理。

死锁

在这里插入图片描述

数据库中出现死锁,数据库是如何解决的?

clientA: 
	1. setautocommit=off 
	2. begin; 
	3. update student set sname=xx where sno=1 
	4.  delete from course where cno=1 
clientB: 
	1. setautocommit=off 
	2. begin; 
	3. update course set..where cno=1 
	4. delete from student where sno=1
mariadb对死锁的处理:检测到死锁后,让一端的事务回滚,并提示DeadLock,让另一端的事务执行成功.

视图 --View-- 笔试题 创建视图

什么是视图

视图是虚拟表,用于展示结果集,其中并不保存数据,其数据来源于真实表中.视图实质上是用于封装sql的,后续若想 再次执行相同的sql,直接调用视图名称即可.

场景:
	在数据库中若要多次展示同样的数据,其数据来源于4表,一样的sql写多次,此时出现了sql重复问题 数据库如何解决这个问题? 
	将上述的sql封装起来,给这个sql起一个名字,后续若想再次执行改sql,直接调用名字即可

操作视图

创建视图

create view view_name as select.......
create view view_name(col1,col2,col3,col4) as select......

调用视图 :

因为视图是虚拟表,所以对视图的操作和对表的操作是一样的

select ...from table_name 
select ...from view_name 
desc table_name; 
desc view_name;

删除视图

drop table table_name 
drop view view_name

视图注意事项:

1. 视图实质上是对sql的封装,而不是对结果集的封装,视图的存在并不是用于提高查询效率的,效率不会提高 
2. 视图的存在是用于查询的,而不是用于对数据进行写操作,所以不应该对视图执行update操作,但是数据库语法 上允许对视图执行update操作,但是不一定成功
		- 视图来源于单表 
			- - 修改 -- 成功 
			- - 删除 -- 成功 
			- - 增加 -- 成功
		- 视图来源于多表
		 	-- 修改
		 			1. 修改一张表的字段 -- 成功 
		 			2. 同时修改2表的字段 -- 失败
		 	-- 删除 -- 失败 
		 	-- 添加 -- 失败
3. 因为视图中并不保存数据,其数据来源于真实表中,所以真实表中的数据发生改变,视图中的数据一定会随之改变

事务隔离级别 – 面试

4种

read uncommitted 读未提交 -- RU 
read committed 读已提交 -- RC 
repeatable read 可重复读 --RR 
serializable 可串行化

读未提交

特点:事务可以读取到其他事务未提交/未回滚前的数据,会产生脏读 
什么是脏读:由于事务读取到了其他事务未提交/未回滚前的数据,导致读取的数据最终是不存在的,这个现象就叫做 脏读.

读已提交

特点:事务只能读取到其他事务提交/回滚后的数据,解决了脏读问题,但是会产生不可重复读问题. 
什么是不可重复读:在事务A执行期间,其他事务对事务A访问的数据进行修改操作,导致事务A中前后两次读取相同的 数据的结果是不一致的.这个现象就叫做不可重复读

可重复读

解决了不可重复读问题,产生了新的问题 -- 幻读 
什么是幻读: 在事务A访问数据期间,其他事务执行了插入操作,导致事务A前后两次读取到的数据总量不一致,这个 现象就叫做幻读.

可串行化

解决了幻读问题,实现了多事务并发执行同步效果,所以这个隔离级别的并发执行效率是最低下的

四种隔离级别由低到高

读未提交-->读已提交-->可重复读-->可串行化

四种隔离级别可能产生的问题

在这里插入图片描述
在这里插入图片描述

数据库默认的隔离级别

oracle和sql server 默认的隔离级别为 读已提交 
mysql的 默认隔离级别为 -- 可重复读

mysql默认的隔离级别可重复读是如何实现的?

存储引擎为Innodb的mysql,其隔离级别可重复读的实现是通过MVCC实现的

MVCC(Multi-Version Concurrency Control)- 多版本并发控制

多版本并发控制解决了并发安全问题,且并发执行效率高很多. 

MVCC的实现由三部分配合实现: 
	1. undolog 
	2. mysql中的表里边每个表都有隐藏的三个字段 
	3. ReadView

隐藏字段

row_id -- Innodb存储引擎提供的隐藏主键 -- 当表中没有主键时自动生成 -- 隐藏主键
DB_trx_id -- 事务的id -- 该列中保存的id值为最后操作该数据的事务id 
DB_roll_ptr -- 数据回滚指针,保存要回滚到的数据的地址

在这里插入图片描述

ReadView

事务执行操作时,会生成当前事务的ReadView,ReadView保存当前事务之前活跃的所有事务id 
ReadView有四个字段: 
	m_ids: 截止到当前事务id之前,所有活跃的事务id 
	min_trx_id: 记录以上活跃事务id中的最小值 
	max_trx_id: 保存当前事务结束后应分配的下一个id值 
	creator_trx_id: 保存创建ReadView的当前事务id

三者如何配合实现mysql的隔离级别

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值