数据库
1.数据库的事务
1.1事务的概念
一组操作要么同时成功,要么同时失败
1.2事务的特性:ACID
a.原子性:Atomicity 当前事务的操作要么同时成功,要么同时失败
实现原理:Undo log 日志来保证,回滚之前的操作的数据
b.一致性:Consistency 使用事务的最终目的,由业务代码正确逻辑保证
c.隔离性:isolation 事务并发执行时,一个事务执行不会影响其他事务的执行
d.持久性:提交事务,对数据库的改变是永久的
2.事务的隔离级别
目的:多个并行事务竞争导致数据安全问题的一种规范
--
a.读未提交:允许事务读取还未提交的数据,可能会出现幻读,脏读,不可重复读
b.读已提交:保证读取到的数据都是已提交的,避免了脏读,但是可能会出现不可重复读和幻读问题。
-mvcc 语句级快照 读最新的
c.可重复读:一个事务多次读取同一个数据,得到一致的结果。保证了事务之间不会相互干扰,但是可能会出现幻读问题,读取到未提交新插入的行。
--mvcc 事务级快照 读第一次查到的
d.串行化:所有事务都会强制化串行执行,保证了同一时间只有一个事务执行
--通过读锁 写锁实现
3.什么是幻读 脏读 不可重复读
参考网址:
脏读,幻读 图解:https://blog.csdn.net/weixin_41814871/article/details/124996364
隔离级别的解释:数据库事务隔离级别有哪些-mysql教程-PHP中文网
Mvvc :https://zhuanlan.zhihu.com/p/582500608
--------------------------------------------------
a.脏读:读到数据库中不存在的数据
b.不可重复读:在一个事务内,多次查询的结果不一致
c.幻读:查询不到数据,插入但是提示数据已存在
*脏写:在可重复读中,读出来的值修改后插入,覆盖了其他事务的值(并发更新覆盖)
--脏写解决方法:乐观锁,添加版本号
4.数据库如何解决这些问题?(mvcc 数据库锁的分类)
提升隔离级别
1.Mvcc :多版本并发控制
场景 解决方法
并发读 无影响
并发写 加锁
并发读写 使读和写做无冲突的并发控制
2.数据库锁的分类
加锁是为了一段时间内保证数据一致性
一、数据库锁的分类:按粒度分类:全局锁,表锁,行锁
(1)全局锁
常见的全局锁有读锁和写锁
读锁:其他用户可以读取数据,不能更改数据。保证数据的一致性。
写锁:其他用户不能读取和更新数据
示范:
使用 fush tables with read lock 开启全局锁,阻止其他线程进行更新操作
可以导出表,备份库,备份表
使用unlock tables语句释放锁
*也可以利用mql的mvcc机制,保证数据的一致性
(2)表锁
表锁分为表共享读锁,表独占写锁 ,表独占读锁
*MyISAM表没有事务
对MyISAM表的读操作,会自动加上读锁,
对MyISAM表的写操作,会自动加上写锁。
InnoDB在必要情况下会使用表锁,主要使用行锁来实现多版本并发控制。
表锁的使用场景:读多写少的场景
mysql哪些命令会发生表级锁
在修改/删除表使防止有数据写入
- alter table
- Drop table/truncate table
- Lock tables
- 全表扫描或大范围扫描 --在MyISAM中
- Flush tables with read lock 全局锁也意味着表也锁掉了
表锁的缺点:
- 性能下降
- 并发性能差
- 可能导致等待和超时
- 写操作性能大
- 死锁的可能性
(3)行锁
行锁:对数据库表的中的单独一行进行锁定
条件:只有在事务中才生效
行锁分为共享锁(读锁)和排他锁(写锁)
使用场景:
行锁优点:
高并发的读写
单行操作
短期锁:及时释放
Mvccc是通过行锁实现
复杂的事务处理
导致发生行锁:
Select .. for update 这种查询会对选定的行添加一个排他锁,这意味着事务不能修改这些行,也不能对这行添加共享锁。
Select .. lock in share mode :这种查询会对选定的行添加一个共享锁,其他事务不能修改这行数据,但可以对这些行进行添加共享锁
Insert 排他
Update 排他
Delete 排他
行锁的缺点:
死锁:
锁升级:锁定的行数过多,占用的cpu过多
锁等待:
资源消耗
二、乐观锁和悲观锁
是两种思想
乐观锁:乐观锁多个事务同时访问一条数据是,冲突发生的概率很低。
先改数据时,不加锁,提交时,判断是否有其他事务修改过,有就回滚,没有就提交。
乐观锁使用场景:
低冲突环境: 读多写少的场景
缺点:
冲突检测:
处理开销:
版本管理:
编程复杂:
悲观锁:
悲观锁认为并发过程中很可能会出现冲突,
因此为了保证数据的完整性和一致性,
每次读写数据的时候先加锁,可以可以避免其他事务进行并发的读写操作
适用场景:
写大于读:
强一致性:付款
实现悲观锁:
缺点:
并发性降低:
死锁:多个事务互相等待释放锁
锁超时:
三 意向锁
意向锁分为:意向共享锁和意向排他锁
概率:意向锁是表锁,为了协调行锁和表锁的关系,支持表锁和行锁的并存。
如果A事务对行数据加了行级读锁,B事务想获得该表的读锁,是兼容的
如果A事务对行数据加了行级读锁,B事务想获得该表的写锁,是不可能的
如果A事务对行数据加了行级写锁,B事务想获得该表的读锁,是不可能的
如果A事务对行数据加了行级写锁,B事务想获得该表的写锁,是不可能的
四 间隙锁
锁定一定范围的行级数据
避免幻读
缺点:
性能
锁定的范围可能过大
五 临键锁
临键锁:特殊的间隙锁