'''
- 事务的概念和特性
- 常见的并发一致性问题
- 数据库的四种隔离级别
- 乐观锁和悲观锁
- 常见的封锁类型
'''
1.事务的概念和特性
概念:事务(Transaction)是一个操作序列,是数据库应用的基本逻辑单位,以BEGIN TRANSACTION开始,以ROLLBACK/COMMIT结束
特性:
- 原子性:不可分割的操作单元,事务的所有操作要么全部提交成功,要么全部失败回滚(用回滚日志实现,反向执行日志中的操作)
- 一致性:事务的执行必须使数据库保持一致性状态。在一致性状态下,多有事务对一个数据的读取结果都是相同的。
- 隔离性:一个事务所做的修改在最终提交以前,对其他事务是不可见的(并发执行的事务之间不能互相影响)
- 持久性:一个事务提交成功,对数据的修改是永久性的
2.常见的并发一致性问题
- 丢失修改:一个事务对数据进行了修改,在事务提交之前,另一个事务对同一数据进行了修改,覆盖了之前的修改
- 脏读:一个事务读取了被另一个事务修改,但是尚未提交(进行了回滚)的数据,造成两个事务得到的数据不一致
- 不可重复读:同一个事务中,某查询操作在一个时间读取某行数据和之后一个时间读取该行数据,发现数据发生修改(针对update操作)
- 幻读:当同一查询多次执行时,由于其它事务在这个数据范围内执行了插入操作,会导致每次返回不同的结果集
(和不可重复读的区别:针对的是一个数据整体/范围;并且针对insert/delete操作)
3.数据库的四种隔离级别
- 未提交读:一个事务提交之前,它的执行结果对其他事务也是可见的(会导致脏读、不可重复读、幻读)
- 提 交 读:一个事务只能看见已经提交的事务所做的改变(可避免脏读问题)
- 可重复读:确保同一个事务在多次读取同样的数据时得到相同的结果集(MySQL的默认隔离级别;可避免不可重复读)
- 可串行化:强制事务串行执行,使之不可能相互冲突,从而解决幻读问题。(可能导致大量的超时现象和锁竞争,实际很少使用)
4.乐观锁和悲观锁
- 悲观锁:认为数据随时会被修改,因此每次读取数据之前都会上锁,防止其他事务读取或修改数据,应用于数据更新较为频繁的场景
- 乐观锁:操作数据时不会上锁,但是更新时会判断在此期间有没有别的事务更新这个数据,若被更新过,则失败重试,适用于读多写少的场景
乐观锁的实现方式:
* 加一个版本号或者时间戳字段,每次数据更新时同时更新这个字段
* 先读取想要更新的字段或者所有字段,更新的时候比较一下,只有字段没有变化才进行更新
5.常见的封锁类型
- 排它锁:(X锁)事务对数据加上X锁时,只允许此事务读取和修改此数据,且其他事务不能对该数据加任何锁
- 共享锁:(S锁)加了S锁之后,该事务只能对数据进行读取而不能修改,并且其它事务只能加S锁,不能加X锁
- 意向锁:
* 一个事务在获得某个数据行对象的S锁之前,必须先获得整个表的IS锁或更强的锁
* 一个事务在获得某个数据行对象的X锁之前,必须先获得整个表的IX锁
* IS/IX锁之间是兼容的
* 好处 -- 如果一个事务想要对整个表加X锁,就需要先检测是否有其他事务对该表或者该表中的某一行加了锁,这种检测非常耗时。
有了意向锁之后,只需要检测整个表是否存在IX/IS/X/S锁就行。
锁的作用:用于管理对共享资源的并发访问,保证数据库的完整性和一致性
意向锁是InnoDB自动加的,不需要用户干预。
对于UPDATE/DELETE/INSERT语句,InnoDB会自动给涉及数据集加排它锁(X)
对于普通SELECT语句,InnoDB不会加任何锁
共享锁:SELECT * FORM table_name WHERE *** LOCK IN SHARE MODE,其他session仍然可以查询记录,并且可对该记录
加share mode的共享锁,但是如果当前事务需要对该记录进行更新操作,则大概率会造成死锁。
排它锁:SELECT * FORM table_name WHERE *** FOR UPDATE,其他session可以查询该记录,但是不能对该记录加共享锁或
排它锁,而是等待获得锁
【随笔】数据库杂记01
最新推荐文章于 2024-09-09 09:47:53 发布