zoukankan      html  css  js  c++  java
  • python事物管理及同步锁

    我们经常会遇到这样子的问题,我给朋友赚钱100,分为两步:

      1)我的账户-100

      2)朋友账户 +100

    看似需求很简单,但是如果在上面的步骤1)结束后,系统崩溃了怎么办?

    数据库中有事物管理,也就是对于一系列的数据库操作,要么全部成功,要不全部失败,这样就保证了数据的一致性。这就是事务管理的原子性。

    以mysql的innodb的事务管理为例,事务管理执行过程如下:

      1)开启事务管理:start transaction

      2)回退操作:rollback,回退到开启事物管理之前,如果在事务管理中设置了savepoint saveplace,执行rollback to saveplace的时候,会会退到设置savepoint之前。

      3)事物提交:commit。将数据结果永久写入数据库中,没办法再执行rollback回退了。

    如果出现上面说的异常情况,我们就需要用到数据库的事务管理。

    如下图:

      我们正常的向数据库插入两条数据:

             

      执行后,会在数据库中多出两条数据,

       

    现在我们将这两条执行语句改一改,将下面一条执行语句改错,在看执行结果:

      

    这时候,我们查看数据库,发现上面一条数据被正常执行并插入数据库了

      

    很明显,上面这个情况,不是我们希望看到的,我们希望的是,在第二条执行语句报错的情况下,我们整个执行数据库的事物都不执行。

    我们再将代码修改一下,加上python里面的事务管理 :

      from django.db import transaction

      

    我们再去查看数据库,就会发现,数据库没有数据,这就达到我们的需求了。

           

     上面这种情况是在单线程下的示例,是没有问题的,但是如果是多线程时,会出现下面这种情况:

      A给B转账100, 这是,程序会先读取B账户,给B账户加100,这个过程中,C也给B转账100,新线程也会操作B账户,给B账户加100,在A转账完成后,发现实际上B的账户只增加了100元。

      这种情况下,为了保证数据的一致性,我们需要引入线程的隔离性,即保证每个线程看到的数据是一致的。这个需要借助【锁】来实现。

      处理这种情况,我们可以用【同步锁】:

      如下,我们创建五个线程同时去操作一个同账户,每次给该账户增加100元,按照我们的预期,最后结果应该是600,但是,从下面的打印,我们可以看出来,最终的结果是300,并不是我们要的600.

      这就是上面说的多线程情况下的数据不一致问题。

              

       下面,我们将代码修改一下:

      

      上面的代码中,我们就加入了同步锁,threading.Lock()

      在数据可能会被同时修改的地方,加上l.accquire() 获得同步锁,然后在资源操作完成后,再将锁释放掉l.release(),给下一个线程使用,这样就避免了数据同时被多个线程修改的问题。

  • 相关阅读:
    bugfree3.0.1-修改“优先级”为中文引起的PHP Error
    【vue】vue单元测试:karma+mocha
    【node】node的核心模块---http模块,http的服务器和客户端
    【node】fs模块,文件和目录的操作
    【webpack】从零开始学webpack
    【vue】webpack插件svg-sprite-loader---实现自己的icon组件
    【vue】vue的路由权限管理
    【node】用koa搭建一个增删改服务(一)
    【小程序】小程序之发送模板消息
    【小程序】返回顶部wx.pageScrollTo和scroll-view的对比
  • 原文地址:https://www.cnblogs.com/fiona-zhong/p/10033396.html
Copyright © 2011-2022 走看看