我们经常会遇到这样子的问题,我给朋友赚钱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(),给下一个线程使用,这样就避免了数据同时被多个线程修改的问题。

python事物管理及同步锁的更多相关文章

  1. python 多线程中的同步锁 Lock Rlock Semaphore Event Conditio

    摘要:在使用多线程的应用下,如何保证线程安全,以及线程之间的同步,或者访问共享变量等问题是十分棘手的问题,也是使用多线程下面临的问题,如果处理不好,会带来较严重的后果,使用python多线程中提供Lo ...

  2. 扯扯python的多线程的同步锁 Lock RLock Semaphore Event Condition

    我想大家都知道python的gil限制,记得刚玩python那会,知道了有pypy和Cpython这样的解释器,当时听说是很猛,也就意味肯定是突破了gil的限制,最后经过多方面测试才知道,还是那德行… ...

  3. python 守护进程、同步锁、信号量、事件、进程通信Queue

    一.守护进程 1.主进程创建守护进程 其一:守护进程会在主进程代码执行结束后就终止 其二:守护进程内无法再开启子进程,否则抛出异常:AssertionError: daemonic processes ...

  4. Thread类的其他方法,同步锁,死锁与递归锁,信号量,事件,条件,定时器,队列,Python标准模块--concurrent.futures

    参考博客: https://www.cnblogs.com/xiao987334176/p/9046028.html 线程简述 什么是线程?线程是cpu调度的最小单位进程是资源分配的最小单位 进程和线 ...

  5. python 全栈开发,Day42(Thread类的其他方法,同步锁,死锁与递归锁,信号量,事件,条件,定时器,队列,Python标准模块--concurrent.futures)

    昨日内容回顾 线程什么是线程?线程是cpu调度的最小单位进程是资源分配的最小单位 进程和线程是什么关系? 线程是在进程中的 一个执行单位 多进程 本质上开启的这个进程里就有一个线程 多线程 单纯的在当 ...

  6. Python并发编程-进程 线程 同步锁 线程死锁和递归锁

    进程是最小的资源单位,线程是最小的执行单位 一.进程 进程:就是一个程序在一个数据集上的一次动态执行过程. 进程由三部分组成: 1.程序:我们编写的程序用来描述进程要完成哪些功能以及如何完成 2.数据 ...

  7. python笔记9 线程进程 threading多线程模块 GIL锁 multiprocessing多进程模块 同步锁Lock 队列queue IO模型

    线程与进程 进程 进程就是一个程序在一个数据集上的一次动态执行过程.进程一般由程序.数据集.进程控制块三部分组成.我们编写的程序用来描述进程要完成哪些功能以及如何完成:数据集则是程序在执行过程中所需要 ...

  8. python全栈开发,Day42(Thread类的其他方法,同步锁,死锁与递归锁,信号量,事件,条件,定时器,队列,Python标准模块--concurrent.futures)

    昨日内容回顾 线程 什么是线程? 线程是cpu调度的最小单位 进程是资源分配的最小单位 进程和线程是什么关系? 线程是在进程中的一个执行单位 多进程 本质上开启的这个进程里就有一个线程 多线程 单纯的 ...

  9. python并发编程之多进程(二):互斥锁(同步锁)&进程其他属性&进程间通信(queue)&生产者消费者模型

    一,互斥锁,同步锁 进程之间数据不共享,但是共享同一套文件系统,所以访问同一个文件,或同一个打印终端,是没有问题的, 竞争带来的结果就是错乱,如何控制,就是加锁处理 part1:多个进程共享同一打印终 ...

随机推荐

  1. HTTP Authentication

    PS:近期看了一本思维导图的书,实践一下.

  2. Python中类的定义及使用

    类是一些有共同特征和行为事务事物的抽象概念的总和. 从中可以看出,方法只能使用实例直接调用(无需传self参数),而使用类调用必须传入实例对象: 属性可以使用实例调用,也可以使用类直接调用,因此可以看 ...

  3. Deep learning深度学习的十大开源框架

    Google开源了TensorFlow(GitHub),此举在深度学习领域影响巨大,因为Google在人工智能领域的研发成绩斐然,有着雄厚的人才储备,而且Google自己的Gmail和搜索引擎都在使用 ...

  4. SQL WHERE 子句

    WHERE 子句 如需有条件地从表中选取数据,可将 WHERE 子句添加到 SELECT 语句. 语法 SELECT 列名称 FROM 表名称 WHERE 列 运算符 值 释意:选取 [列] 来自 [ ...

  5. ALTER添加列后,立即UPDATE该列会报错

    SQL 2008 R2 请看语句: ALTER TABLE #t ADD col2 INT UPDATE #t SET col2 = 0 报错:列名'col2'无效. 但如果紧接的是SELECT,一切 ...

  6. emacs 绑定快捷键 c/c++

    ;;跳转到函数定义的地方 (global-set-key (kbd "C-<f2>") 'ggtags-find-definition) ; Control+F2 ;; ...

  7. Google开源GSON的使用

    * 谷歌开原项目GitHub地址:https://github.com/google/gson 1.新建一个maven项目,引入gson的dependency坐标依赖以及commons-io的坐标: ...

  8. Linux中的文件查找技巧

    前言 Linux常用命令中,有些命令可以帮助我们查找二进制文件,帮助手册或源文件的位置,也有的命令可以帮助我们查找磁盘上的任意文件,今天我们就来看看这些命令如何使用. witch witch命令会在P ...

  9. 【Teradata】数据库初始化(sysinit和dip工具)

    1.删除数据库对象 (1)使用root用户登录数据库节点 arcmain .LOGON 127.0.0.1/dbc,dbc_password; (2)清理所有数据库对象及数据 DELETE DATAB ...

  10. node express 上传文件

    npm install --save multer var fs = require('fs'); var multer = require('multer'); var upload = multe ...