多任务数据修改处理&数据库事务隔离级别

  • 在程序中对数据库数据进行变动的时候,如果该段程序是并发的就很容易出现数据修改紊乱的问题,多任务同时进行修改同一个数据,这时候需要一个解决方法。
    • 悲观锁
    • 乐观锁
    • 任务队列
  1. 悲观锁:
    - 当我们查询一条记录的时候,就会让数据库对该记录进行上锁,原理类似于多线程的时候的互斥锁处理,实现了数据的完整性,缺点就是容易出现死锁现象,一旦出现死锁,程序就崩了,所以悲观锁的使用会造成程序不稳定,不推荐使用

  2. 任务队列:
    - 例如可以使用selery模块来实现,开启单任务模式的celery,将数据修改逻辑代码添加到celery中,但是此时程序就不能实现并发,任务的执行效率会大大降低,所以不是很好用

  3. 乐观锁:
    - 乐观锁并没有实际的锁的逻辑,而是在商品更改之前跟更改之时都进行原数据的查询,确认修改的时候数据是更改之前一致,因为此时可以确保原数据没有被其他线程等多任务修改过,所以可以安全地对数据库进行修改,

    old_name
    user.id
    new_name
    ret=Model.object.filter(name=old_name,id=user.id).update(name=new_name)
    # 如果修改成功ret会得到1的返回值,否则返回0,
    
包含乐观锁的任务逻辑可以放在一个死循环里边,修改失败则使用continue关键字重新尝试修改,直到修改成功的时候,继续下边的业务逻辑,break关键字退出循环。
乐观锁需要在修改的时候查询数据库信息,而mysql默认的事务隔离级别为可重复读(repeatable),而乐观锁需要在事务里边读取到即时数据,所以需要修改事务隔离级别为read-commit

事务隔离级别

事务隔离级别脏读不可重复读幻读
读未提交(read-uncommitted)
不可重复读(read-committed)
可重复读(repeatable-read)
串行化(serializable)

脏读: 脏读就是指当一个事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中,这时,另外一个事务也访问这个数据,然后使用了这个数据。
不可重复读:是指在一个事务内,多次读同一数据。在这个事务还没有结束时,另外一个事务也访问该同一数据。那么,在第一个事务中的两次读数据之间,由于第二个事务的修改,那么第一个事务两次读到的的数据可能是不一样的。这样就发生了在一个事务内两次读到的数据是不一样的,因此称为是不可重复读。
幻读:第一个事务对一个表中的数据进行了修改,这种修改涉及到表中的全部数据行。同时,第二个事务也修改这个表中的数据,这种修改是向表中插入一行新数据。那么,以后就会发生操作第一个事务的用户发现表中还有没有修改的数据行,就好象发生了幻觉一样。

  • 未提交读(Read Uncommitted):允许脏读,也就是可能读取到其他会话中未提交事务修改的数据

  • 提交读(Read Committed):只能读取到已经提交的数据。Oracle等多数数据库默认都是该级别 (不重复读)

  • 可重复读(Repeated Read):可重复读。在同一个事务内的查询都是事务开始时刻一致的,InnoDB默认级别。在SQL标准中,该隔离级别消除了不可重复读,但是还存在幻象读

  • 串行读(Serializable):完全串行化的读,一个一个地执行,每次读都需要获得表级共享锁,读写相互都会阻塞

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值