数据不一致性是数据库并发控制中的关键问题,它可能由并发事务的交互导致,对数据的完整性和一致性产生破坏。在数据库系统中,主要有三种数据不一致性现象:丢失修改、不能重复读和读“脏”数据。
1. **丢失修改(Lost Update)**:当两个并发事务同时修改同一数据时,如果一个事务在修改后立即提交,而另一个事务还在读取旧值进行修改,可能导致结果的不一致。如例子所示,事务T1先读取A=50和B=100,然后T2修改B,这时T1再读取到B=200,最终计算结果与预期不符。
2. **不能重复读(Non-Repeatable Read)**:在一个事务内,同一个查询结果因并发事务的插入或更新而改变,使得事务无法再次获得相同的读取结果。例如,T1第一次读取C=100,接着T2将C变为200,即使T1回滚,C的值也会改变,导致T1下次读取的C不再是原始值。
3. **读“脏”数据(Dirty Read)**:事务T读取的数据是另一个事务未提交修改的结果,这种情况下,T可能看到的是“半成品”的数据,而非最新的数据版本。例如,T1读取A=16,随后T2更新A,但T1还未结束,其结果是T1读到了T2的未提交修改值。
并发控制的目标是确保数据的一致性,通过各种机制来协调多个事务的执行。常见的并发控制技术包括:
**1. 封锁(Locking)**
- **定义**:事务在访问数据前,先申请锁定,以防止其他事务同时修改。
- **种类**:
- **排他锁/写锁(X锁)**:事务持有X锁时,其他事务只能等待,禁止读取和修改该数据,直到X锁释放。
- **共享锁(S锁)**:允许其他事务读取但禁止修改,多个事务可以共享同一数据的S锁。
**2. 时间戳(Timestamp)**:利用时间戳来决定事务的执行顺序,确保在一个事务结束前,其修改不会影响其他事务。
**3. 乐观控制法**:假设大部分事务不会冲突,直到提交时才检查数据冲突,若有冲突则回滚并重新开始,降低锁定带来的开销。
并发调度策略包括串行执行和并行执行。串行执行保证了事务的原子性和一致性,但资源利用率低;并行执行(如在多处理机系统中的同时并发)可以提高效率,但需妥善处理并发带来的数据不一致性风险。
理解并掌握这些概念和方法对于设计和维护高效、一致的数据库系统至关重要,有助于预防和解决数据不一致性问题,保证数据的可靠性。