事务隔离是怎么实现的?有哪些锁?
两种锁
- 排他写锁(X 锁):若事务 T1 对数据对象 A 加上 X 锁,则只允许 T 读取和修改 A,其他任何事物都不能再对 A 加任何类型的锁,直到 T 释放 A 上的锁为止。
- 共享读锁(S 锁):若事务 T 对数据 A 加上 S 锁,则事务 T 可以读 A 但是不能修改 A,其他事务只能对 A 加 S 锁而不能加 X 锁,直到 T 释放 A 上的 S 锁为止。所以它的最主要作用是阻塞 X 锁。
三级加锁协议(可解决脏读和不可重复读)
一级加锁协议(无法避免脏读、不可重复读)
- 如果只对数据进行读操作,不需要加锁。
- 如果对数据进行写操作,需要加 X 锁直至事务结束。
二级加锁协议(可避免脏读,无法避免不可重复读)
在一级加锁协议的基础上,添加操作:事务 T 在读取数据 R 前要对 R 加上 S 锁,读完之后即可释放 S 锁,无需等待事务结束。
三级加锁协议(可避免脏读、不可重复读)
基本与二级加锁协议相同,只是 S 锁加上之后要等到事务结束才能释放。
3 种锁:
- Record Locks(记录锁):在索引记录上加锁。
- Gap Locks(间隙锁):在索引记录之间加锁,或者在第一个索引记录之前加锁,或者在最后一个索引记录之后加锁,可避免幻读。
- Next-Key Locks:在索引记录上加锁,并且在索引记录之前的间隙加锁。它相当于是 Record Locks 与 Gap Locks 的一个结合。
什么是乐观锁?悲观锁?实现方式?
悲观锁: 每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻塞直到它拿到锁,虽然安全,但并发性极差,如 Java 的 synchronized。
乐观锁: 每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在提交更新的时候会判断一下在此期间别人有没有去更新这个数据,如 CAS。
……