乐观锁是一种并发控制机制,用于处理多个事务或线程对同一数据进行并发修改的问题。它假设多个事务或线程在操作数据时不会互相干扰,因此不在数据上加锁,而是在提交数据时检查数据是否被其他事务修改过。如果数据在提交前已经被其他事务修改,则当前事务需要重新读取数据并尝试再次提交。乐观锁的核心思想是“乐观地”认为数据冲突的概率很低,因此主要在提交阶段进行冲突检测。
乐观锁的实现方式
乐观锁的常见实现方式是使用版本号或时间戳:
-
版本号(Version Number):
- 在数据表中增加一个版本号字段,每当数据被修改时,版本号加1。
- 事务在读取数据时,会同时读取版本号。
- 在更新数据时,事务会检查当前数据的版本号是否与读取时的版本号一致。如果一致,则进行更新并将版本号加1;如果不一致,则说明数据已经被其他事务修改,当前事务需要重新读取数据再进行处理。
-
时间戳(Timestamp):
- 在数据表中增加一个时间戳字段,记录数据的最后修改时间。
- 事务在读取数据时,会同时读取时间戳。
- 在更新数据时,事务会检查当前数据的时间戳是否与读取时的时间戳一致。如果一致,则进行更新并更新时间戳;如果不一致,则说明数据已经被其他事务修改,当前事务需要重新读取数据再进行处理。
示例代码
以下是一个使用版本号实现乐观锁的示例:
数据表设计
CREATE TABLE user (
id BIGINT PRIMARY KEY,
name VARCHAR(50),
balance DECIMAL(10, 2),
version INT