为什么Zookeeper天生就是一副分布式锁的胚子?
update goods set goods_num = goods_num -1,version =查询的version值自增 where goods_name ="小本子" and version=查询出来的version; 其实,借助更新时间戳(updated_at)也可以实现乐观锁,和采用 version 字段的方式相似。 更新操作执行前线获取记录当前的更新时间,在提交更新时,检测当前更新时间是否与更新开始时获取的更新时间戳相等。 悲观锁 除了可以通过增删操作数据库表中的记录以外,我们还可以借助数据库中自带的锁来实现分布式锁。 在查询语句后面增加 FOR UPDATE,数据库会在查询过程中给数据库表增加悲观锁,也称排他锁。当某条记录被加上悲观锁之后,其它线程也就无法再改行上增加悲观锁。 悲观锁,与乐观锁相反,总是假设最坏的情况,它认为数据的更新在大多数情况下是会产生冲突的。 在使用悲观锁的同时,我们需要注意一下锁的级别。MySQL InnoDB 引起在加锁的时候,只有明确地指定主键(或索引)的才会执行行锁 (只锁住被选取的数据),否则 MySQL 将会执行表锁(将整个数据表单给锁住)。 在使用悲观锁时,我们必须关闭 MySQL 数据库的自动提交属性(参考下面的示例),因为 MySQL 默认使用 autocommit 模式。 也就是说,当你执行一个更新操作后,MySQL 会立刻将结果进行提交。 mysql> SET AUTOCOMMIT = 0; Query OK, 0 rows affected (0.00 sec) 这样在使用 FOR UPDATE 获得锁之后可以执行相应的业务逻辑,执行完之后再使用 COMMIT 来释放锁。 我们不妨沿用前面的 database_lock 表来具体表述一下用法。假设有一线程A需要获得锁并执行相应的操作。 那么它的具体步骤如下: STEP1 - 获取锁:SELECT * FROM database_lock WHERE id = 1 FOR UPDATE;。 STEP2 - 执行业务逻辑。 STEP3 - 释放锁:COMMIT。 作者:凌晶 (编辑:晋中站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |