可重复读取(Repeatable
Read):禁止不可重复读取和脏读取,但是有时可能出现幻读数据。这可以通过“共享读锁”和“排他写锁”实现。读取数据的事务将会禁止写事务(但允许读事务),写事务则禁止任何其他事务。
序列化(Serializable)
序列化(Serializable):提供严格的事务隔离。它要求事务序列化执行,事务只能一个接着一个地执行,不能并发执行。仅仅通过“行级锁”是无法实现事务序列化的,必须通过其他机制保证新插入的数据不会被刚执行查询操作的事务访问到。
隔离级别越高,越能保证数据的完整性和一致性,但是对并发性能的影响也越大。对于多数应用程序,可以优先考虑把数据库系统的隔离级别设为Read
Committed。它能够避免脏读取,而且具有较好的并发性能。尽管它会导致不可重复读、幻读和第二类丢失更新这些并发问题,在可能出现这类问题的个别场合,可以由应用程序采用悲观锁或乐观锁来控制。
乐观锁机制采取了更加宽松的加锁机制。悲观锁大多数情况下依靠数据库的锁机制实现,以保证操作最大程度的独占性。但随之而来的就是数据库
性能的大量开销,特别是对长事务而言,这样的开销往往无法承受。相对悲观锁而言,乐观锁更倾向于开发运用。
悲观锁,正如其名,具有强烈的独占和排他特性。它指的是对数据被外界(包括本系统当前的其他事务,以及来自外部系统的事务处理)修改持保守态度,因此,在整个数据处理过程中,将数据处于锁定状态。悲观锁的实现,往往依靠数据库提供的锁机制(也只有数据库层提供的锁机制才能真正保证数据访问的排他性,否则,即使在本系统中实现了加锁机制,也无法保证外部系统不会修改数据)
SQL标准定义的事务隔离级别有哪些共4个:
读未提交
读已提交
可重复读
可串行化
注意: SQL定义的这4种隔离级别, 只定义了哪种现象不能发生,
但没有定义哪种现象一定发生.
在PG系统中, 事务的隔离级别所涉及的最小实体是元组, 即: Tuple.
所以对元组的操作(例如读取, 插入, 更新, 删除)需要实施访问控制,
它们是通过锁操作以及MVCC相关的操作来实现的.
共3种:
SpinLock
LWLock
RegularLock
SpinLock的特点是: 封锁时间很短, 没有等待队列和死锁检测机制,
事务结束时不能自动释放SpinLock.
作为一种最底层的锁, 一般不直接使用SpinLock, 而是利用它来实现其他锁(LWLock).
LWLock(轻量级锁): 主要提供对共享存储器的数据结构的互斥访问.
LWLock有2种锁模式: 1) 排他模式 2) 共享模式.
LWLock不提供死锁检测, 但在elog恢复期间被自动释放,
所以持有轻量级锁的期间调用elog发出错误信息不会出现轻量级锁未释放的问题.
LWLock的特点是: 有等待队列, 无死锁检测, 能自动释放锁.
RegularLock就是一般数据库事务管理中所指的锁, 也简称为Lock.
RegularLock由LWLock实现, 其特点是: 有等待队列, 有死锁检测, 能自动释放锁.
7.8 锁管理机制 PG都有哪些粒度的锁, 锁的对象分别是谁5种:
表粒度的锁
页粒度的锁
元组粒度的锁
事务粒度的锁
一般对象的锁
表粒度的锁操作表示在数据库系统中加锁对象为一个表.
页粒度的锁操作表示在数据库系统中加锁 对象为一个页面.
元组….对象为一个元组.
事务粒度..对象为一个事务.
一般对象…对象为一般对象.
各个粒度的锁操作具体是怎样的 表粒度的锁操作 页粒度的锁操作 元组粒度的锁操作 事务粒度的锁操作 一般对象的锁操作 7.9 死锁处理机制 死锁处理机制在PG中, 当进程不能获得锁进入等待队列时, 就会触发死锁检测的操作.
如果发现了”死锁”, 进而尝试进行死锁的解除操作,
死锁解除采用枚举的方法尝试调整队列中进程的等待先后拓扑顺序,
试图找到一种打破进程之间循环等待的状态.
PG为开发者提供了丰富的管理数据库并发访问的工具. 在内部,
PG利用MVCC来维护数据的一致性.
这就意味着当检索数据时, 每个事务看到的只是一段时间之前的数据快照,
而不是数据库的当前状态(即: 最新的状态).
这样, 如果对数据库会话进行事务隔离,
就可以避免一个事务看到其他并发事务的更新而导致不一致的数据.