django上下文事务与锁:保正数据的全局一致

django用select_for_update加锁,必须在事务中使用,而且这是悲观锁,

那么它加的是行锁还是表锁,这就要看是不是用了索引/主键。

没用索引/主键的话就是表锁,否则就是是行锁。

django建立索引:

通过db_index和Meta index选项给数据表字段建立索引

使用索引可快速访问数据库表中的特定信息。数据库索引好比是一本书前面的目录,没有索引目录的话,你访问书中某个页面需要从第1页遍历到最后一页,如果有目录,你可以快速地根据目录查找到所需要的页面。Django项目中如果你需要频繁地对数据表中的某些字段(如title)使用filter(), exclude()和order_by()方法进行查询,我们强烈建议你对这些字段建议索引(index), 提升查询效率。

要对模型中的某个字段建立数据库索引,你可以使用db_index选项,也可以使用Meta选项建立索引。使用Meta选项的好处是你可以一次性对多个字段建立索引,还可以对多个字段建立组合索引。

方法一: 使用db_index选项

class Article(models.Model):    
    """文章模型"""    
    # 使用db_index=True对title建立索引    
    title = models.CharField('标题', max_length=200, db_index=True)


方法二: 使用Meta选项

class Article(models.Model):    
    """文章模型"""   
    title = models.CharField('标题', max_length=200,)    

    class Meta:        
        indexes = [models.Index(fields=['title']),]

django上下文事务正确语法结构 :

from django.db import transaction  
try:
    with transaction.atomic():
        dosomething_1()
        dosomething_2()
        
except Exception as e:
   # 事务出错,将会自动回滚,在这里可以做事务失败后的其他操作
    ...
else:
    ...
finally:
    ...

 示例:

try:
    # 开启事物 用select_for_update() 给需要用到的资源统一加锁,保证事务隔离
    with transaction.atomic():
        GoodsAttribute.objects.select_for_update().filter(uuid__in=[
            goods_attribute.get('goods_attribute_uuid')
            for goods_attribute in goods_attribute_list
        ])
        for goods_attribute in goods_attribute_list:
            goods_attribute_obj = GoodsAttribute.objects.filter(
                uuid=goods_attribute.get(
                    'goods_attribute_uuid')).first()
            goods_number = goods_attribute.get('goods_number')
            if update:
                order_detail_obj = OrderDetail.objects.filter(
                    uuid=goods_attribute.get(
                        'order_detail_uuid')).first()
                add_goods_number = goods_number - order_detail_obj.goods_number
            else:
                add_goods_number = goods_number
            if not goods_attribute_obj or goods_attribute_obj.stock < add_goods_number:
                raise ValidationError(error_msgs.LOW_STOCKS)
            else:
                amount += goods_attribute_obj.price * goods_number
                goods_attribute_obj.stock -= add_goods_number
                goods_attribute_obj.save()
# 异常后事务自动回滚
except:
    raise ValidationError(error_msgs.LOW_STOCKS)

你可能感兴趣的:(django,python,mysql,big,data)