本文目录导读:

在Python数据API中实现乐观锁,常见的方法是使用版本号(version)或时间戳(timestamp)机制,以下是具体实现方式:
基于版本号的乐观锁实现
数据库模型示例 (SQLAlchemy)
from sqlalchemy import Column, Integer, String, DateTime
from sqlalchemy.ext.declarative import declarative_base
import datetime
Base = declarative_base()
class Product(Base):
__tablename__ = 'products'
id = Column(Integer, primary_key=True)
name = Column(String(100))
price = Column(Integer)
stock = Column(Integer)
version = Column(Integer, default=1) # 版本号字段
updated_at = Column(DateTime, default=datetime.datetime.utcnow)
更新操作实现乐观锁
from sqlalchemy.orm import Session
from sqlalchemy import update
def update_product_with_optimistic_lock(session: Session, product_id: int,
new_price: int, expected_version: int):
"""
使用乐观锁更新商品价格
"""
# 查询当前记录
product = session.query(Product).filter_by(id=product_id).first()
if not product:
return {"success": False, "error": "产品不存在"}
# 检查版本号
if product.version != expected_version:
return {"success": False, "error": "数据已被修改,请刷新后重试"}
# 执行更新(版本号+1)
stmt = (
update(Product)
.where(Product.id == product_id)
.where(Product.version == expected_version) # 关键条件
.values(
price=new_price,
version=Product.version + 1,
updated_at=datetime.datetime.utcnow()
)
)
result = session.execute(stmt)
session.commit()
if result.rowcount == 0:
return {"success": False, "error": "乐观锁冲突,更新失败"}
return {"success": True, "message": "更新成功"}
基于时间戳的乐观锁
from datetime import datetime
class User(Base):
__tablename__ = 'users'
id = Column(Integer, primary_key=True)
name = Column(String(50))
balance = Column(Integer)
lock_version = Column(String(32)) # 存储时间戳的哈希值
def before_update(self):
self.lock_version = str(datetime.utcnow().timestamp())
# 更新函数
def update_user_balance(session: Session, user_id: int,
new_balance: int, current_lock_version: str):
user = session.query(User).filter_by(id=user_id).first()
if user.lock_version != current_lock_version:
return {"success": False, "error": "数据已被修改"}
user.balance = new_balance
user.before_update() # 更新锁版本
session.commit()
return {"success": True}
FastAPI + 乐观锁示例
from fastapi import FastAPI, HTTPException, Depends
from pydantic import BaseModel
from sqlalchemy.orm import Session
app = FastAPI()
class ProductUpdate(BaseModel):
id: int
name: str
price: float
version: int # 客户端传递当前版本号
@app.put("/products/{product_id}")
async def update_product(
product_id: int,
product_update: ProductUpdate,
db: Session = Depends(get_db)
):
# 使用原生SQL实现乐观锁
from sqlalchemy import text
sql = text("""
UPDATE products
SET name = :name,
price = :price,
version = version + 1,
updated_at = NOW()
WHERE id = :id
AND version = :expected_version
""")
result = db.execute(sql, {
"id": product_id,
"name": product_update.name,
"price": product_update.price,
"expected_version": product_update.version
})
db.commit()
if result.rowcount == 0:
raise HTTPException(
status_code=409,
detail="数据已被其他用户修改,请刷新后重试"
)
return {"message": "更新成功"}
使用Redis实现乐观锁
import redis
import json
r = redis.Redis(host='localhost', port=6379, db=0)
def update_with_redis_optimistic_lock(key: str, update_func, retry=3):
"""
使用Redis WATCH命令实现乐观锁
"""
with r.pipeline() as pipe:
while True:
try:
# 监控key
pipe.watch(key)
# 读取当前数据
current_data = json.loads(pipe.get(key))
# 执行更新逻辑
new_data = update_func(current_data)
# 开始事务
pipe.multi()
pipe.set(key, json.dumps(new_data))
pipe.execute()
return True
except redis.WatchError:
# 数据被修改,重试
retry -= 1
if retry <= 0:
raise Exception("更新失败,多次重试后仍冲突")
continue
最佳实践
数据库层实现(推荐)
-- 在数据库层面实现乐观锁
CREATE TABLE products (
id INT PRIMARY KEY,
name VARCHAR(100),
price DECIMAL(10,2),
stock INT,
version INT DEFAULT 1,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
-- 更新时检查版本号
UPDATE products
SET price = 100,
version = version + 1
WHERE id = 1
AND version = 1; -- 期望的版本号
客户端代码
class ProductService:
def update_product(self, product_id, new_price, expected_version, max_retries=3):
retry_count = 0
while retry_count < max_retries:
result = self.db.execute(...)
if result.rowcount > 0:
return {"success": True}
retry_count += 1
# 获取最新版本号
product = self.get_product(product_id)
expected_version = product.version
return {"success": False, "error": "更新失败,请重试"}
注意事项
- 版本号管理:确保版本号在每个更新操作中自增
- 事务隔离:选择合适的数据库隔离级别(推荐READ COMMITTED)
- 重试策略:出现冲突时,建议实现指数退避重试
- 并发控制:乐观锁适用于并发不高、冲突少的场景
- 数据一致性:结合数据库约束确保数据完整性
通过以上实现,可以在Python数据API中有效使用乐观锁,避免数据更新冲突。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播