Skip to main content

数据库并发

并发概念

并发在操作系统当中指的是,同一个时间段内有多个程序在运行,这些程序都是在同一个机器上运行,但是任何一个时间点只会运行一个程序,但是CPU可以在不同程序之间分配资源,未分配到资源的程序就被暂时挂起,没有任何动作,但还是处于运行状态。

并发在数据库系统中指的是,当多个用户同时访问和更改共享数据的进程,通过锁机制控制多个用户访问和更改共享数据使得彼此之间不发生冲突。因为如果发生冲突就会导致产生脏数据,导致数据的访问和更改不同步,而且产生了不是我们预期之内的数据。

例子:

  • 飞机订票系统
    1. 甲有16张票,乙某一个时刻读出来也是16张机票
    2. 当甲卖出去一张,修改数量为15张,写回数据库
    3. 当乙也卖出去一张,但是因为之前数据还没更新,又卖给了下一个人,导致数据不同步,就得不到我们预期想要的结果。

判断操作是否可以并发

判断读取集合和写入集合、写入和写入集合是否有交集,有交集说明他们之间有共同的一个操作,所以就不能并发。也就是说只要没有同时操作一个操作就可以并发。假设现在有两个事务T1,T2T_1,T_2R(T1)R(T_1)表示T1T_1事务对所有进行了读取操作的属性,W(T1)W(T_1)表示T1T_1事务对所有进行了写入操作的属性。完整判断流程:(R(T1)W(T2))(R(T2)W(T1))(W(T1)W(T2))(R(T_1)\cap W(T_2))\cup(R(T_2)\cap W(T_1))\cup(W(T_1)\cap W(T_2))看这个表达式是否为空。

例子: 事务T1T_1:R(A),R(B)R(A),R(B),求和;事务T2T_2:R(B)=x,B=B2,W(B);R(B)=x,B=B*2,W(B);

此时R(T1)={A,B}R(T_1)=\{A,B\},W(T2)={B}W(T_2)=\{B\}

并发控制

通过引入锁机制来对并发进行控制,一般读的时候使用共享锁(S锁),因为读操作不会对数据库操作进行修改,所以可以多端进行访问,加上共享锁即可;写的时候使用排它锁(X锁),因为写入是对数据库内容进行修改,如果两端同时写入就可能会产生脏数据,也就是上面那种情况,所以加上排它锁就不会让多个人同时把数据写入数据库。(本质就是读的时候不能写,写的时候不能读),S锁和X锁不能同时加,需要进行等待。

判断调度是否正确

将两个事务串行化运行一遍之后,跟并行运行的结果进行对比,若结果相同说明调度正确,若结果不相同说明调度错误。

判断是否可以串行化

判断读取集合和写入集合、写入和写入集合是否有交集,同时符合两段锁协议,也就是要先申请完所有的锁之后,才能开始解锁。

保证调度的正确性

使用封锁机制可以保证调度正确性。

两段锁协议

事务分两个阶段对数据项加锁和解锁。

  • 第一阶段: 扩展阶段

事务可以申请获得任何数据项上的任何类型的锁,但是不能释放任何锁。

  • 第二阶段: 收缩阶段

事务可以释放任何数据项上的任何类型的锁,但是在释放一个封锁之后,事务不能再申请和获得任何其它封锁。