数据库事务和并发控制

事务特征(ACID):

  1. 原子性:事务的操作要么全做要么全不做。
  2. 一致性:事务操作的结果是一个一致状态转换到另一个一致状态。
  3. 隔离性:一个事务的执行过程不能受到其他事务的干扰。
  4. 持久性:事务一旦提交,对数据库做出的更新将是永久的。

并发产生问题:

  1. 丢失修改:修改的数据被覆盖
  2. 脏读:读取到未提交的数据。
  3. 不可重复读:同一个事务两次读结果不一致。
  4. 幻读:一个事务读到了另一个事务中insert的数据,好像出现了幻觉。

数据库的隔离级别:

这里写图片描述

并发控制的技术:

  • 数据库锁

    排它锁(X锁):写锁,一个事务获取了写锁,则其他事务都不能再加任何类型的锁,直到锁释放。

    共享锁(S锁):读锁,一个事务获取了读锁,其他事务能加读锁,不能加写锁。

(1) 锁协议:
1、一级封锁协议:事务在修改数据前先加写锁,直到事务结束。(防止更新丢失)
2、二级封锁协议:在一级的基础上,事务读数据先加读锁,读完释放读锁。(防止脏读)
3、三级封锁协议:在一级的基础上,事务读数据先加读锁,直到事务结束释放。(防止不可重复读)

(2)两端封锁协议:事务执行过程中,不允许加锁释放锁交叉执行。

加锁阶段:在该阶段可以进行加锁操作。在对任何数据进行读操作之前要申请并获得S锁,在进行写操作之前要申请并获得X锁。加锁不成功,则事务进入等待状态,直到加锁成功才继续执行。

解锁阶段:当事务释放了一个封锁以后,事务进入解锁阶段,在该阶段只能进行解锁操作不能再进行加锁操作。

两段封锁法可以这样来实现:事务开始后就处于加锁阶段,一直到执行ROLLBACK和COMMIT之前都是加锁阶段。ROLLBACK和COMMIT使事务进入解锁阶段

(3)InnoDB行锁算法:
行记录锁:
间隙锁:锁定一个范围。
next-key lock: 锁定一个范围,并锁定记录。

  • 写时复制:读操作一般远远超过写操作,COW读操作不用加锁,极大提高读取性能。

  • 多版本并发控制

    MVCC可以提供基于某个时间点的快照,使得对于事务看来,总是可以提供与事务开始时刻相一致的数据,而不管这个事务执行的时间有多长.所以在不同的事务看来,同一时刻看到的相同行的数据可能是不一样的,即一个行可能有多个版本。

    为了实现mvcc, innodb对每一行都加上了两个隐含的列,其中一列存储行被更新的”时间”,另外一列存储行被删除的”时间”. 但是innodb存储的并不是绝对的时间,而是与时间对应的数据库系统的版本号,每当一个事务开始的时候,innodb都会给这个事务分配一个递增的版本号,所以版本号也可以被认为是事务号.对于每一个”查询”语句,innodb都会把这个查询语句的版本号同这个查询语句遇到的行的版本号进行对比,然后结合不同的事务隔离等级,来决定是否返回该行.

锁带来的问题:

1、活锁:
某一事务一直在等待锁。采用先来先服务的策略。
2、死锁:
事务互相等待锁。
预防:一次将所有需要的数据全部加锁;规定一个封锁顺序
诊断死锁并解除:超时法;等待图法,如果有环则有死锁。解除死锁:选择回滚代价最小的事务;回滚多远;避免饿死。

锁的粒度越大,能够封锁的单元就越少,其并发度越低,系统开销越小。一个系统支持多个封锁粒度供不同的事务选择,叫多粒度封锁。

多粒度锁协议:对一个结点加锁意味着这个节点的所有后裔节点都被加同样的锁。显示封锁:直接加到数据对象的锁,隐式封锁:该数据对象是由于上级节点加锁而加上的锁。

意向锁:对任意节点加锁,就必须先对它的上层节点加意向锁。意向共享锁,意向排他所,共享意向排他锁。

猜你喜欢

转载自blog.csdn.net/qq_33394088/article/details/80078505