在并发编程中,锁是一种常用的机制,用于保护共享资源的访问。乐观锁和悲观锁是两种不同的锁机制。
乐观锁:不会一开始就加锁,在更新的时候,判断一下在此期间别人是否修改了数据,若修改了不执行此操作,反之执行;优点:出现并发冲突小时,乐观锁更好,悲观锁会锁住代码块或者数据,其他线程无法访问,影响并发,而且锁的创建和释放都会消耗资源;这种锁机制适合于多读少写的场景,如缓存中的数据更新。
实例:之前在做家具网时,有人买家具,可能同时买,先判断原始存量,然后在更新的时候再查询一次,如果相同就更新数据量,不同就进入循环重新判断。
悲观锁:操作数据时,直接将锁锁住,直到操作结束:优点:出现并发冲突大的时候,悲观锁更好,乐观锁频繁失败,需要不断重试,浪费CPU资源。这种锁机制适合于多写少读的场景,如数据库中的事务处理。
实例1:flask-sqlalchemy(with_for_update方法)
organization = Organization.query.filter_by(id=organization_id).with_for_update().first()
# 上锁
organization.balance = organization.balance - 1
db.session.commit()
# 保存之后就自动解锁
因为sqlalchemy是缓存机制,此方法可能不会生效,造成行锁没有锁到的结果
所以要在上锁之前加一个将事务提交的操作
# 加上事务提交的方法
db.session.commit()
organization = Organization.query.filter_by(id=organization_id).with_for_update().first()
# 上锁
organization.balance = organization.balance - 1
db.session.commit()
# 保存之后就自动解锁
https://blog.csdn.net/qq_33763224/article/details/115018371
在Python中,可以使用线程锁来实现悲观锁,如使用threading.Lock()
;也可以使用一些乐观锁的实现,如使用类似redis
的分布式锁,或者使用version
来实现乐观锁。
在实现并发控制时,应该根据具体的实际情况来选择使用乐观锁还是悲观锁,一般来说,如果并发请求较少且竞争不激烈,可以使用乐观锁;如果并发请求比较多并且竞争激烈,则应该使用悲观锁。