一、乐观锁说明
乐观锁的使用原理是在数据表中添加一个版本字段,每次先查询当前的版本,在更新数据的时候判断版本是否和查询到的版本一致,一致就说明数据没有被修改,可以操作数据并把版本号+1;如果版本号不一致就说明数据已经被更改了,不进行操作。
相对悲观锁来说,乐观锁用得更广泛一点,但乐观锁的缺点是操作失败率高。假设同一时刻有100个线程读取了数据的版本为1,只要其中一个成功更新了数据,那么剩下的99都会失败,失败率高达(n-1)/n
。
二、使用方法
乐观锁有两种常用的版本控制方法。
第一种方法是在数据库中加入版本字段,每次操作后把版本+1。
第二种方法同样也是插入新字段,只是插入的字段类型为时间戳,在更新数据时先判断时间戳是否一致。
两者原理一样,只是实现的方式不同。
三、示例
创建一个表:
1 2 3 |
create table lock_test( id int primary key, name varchar(20), version int); -- 插入一行数据 insert into lock_test values(1, "maqian", 0); |
开启两个终端,查询id=1
的记录并记下版本号为0
:
1 2 3 4 5 6 7 |
mysql> select * from lock_test where id = 1; +----+--------+---------+ | id | name | version | +----+--------+---------+ | 1 | maqian | 0 | +----+--------+---------+ 1 row in set (0.00 sec) |
当要更新数据的时候根据带上版本号更新:
1 2 3 |
mysql> update lock_test set name = "xiaoming", version = version + 1 where id = 1 and version = 0; Query OK, 1 row affected (0.03 sec) Rows matched: 1 Changed: 1 Warnings: 0 |
第二个终端再根据0
的版本号更新数据就不会操作成功:
1 2 3 |
mysql> update lock_test set name = "xxxxxx", version = version + 1 where id = 1 and version = 0; Query OK, 0 rows affected (0.00 sec) Rows matched: 0 Changed: 0 Warnings: 0 -- 影响行数为0 |
评论