记一个python+sqlalchemy+tornado的一个高并发下,产生重复记录的bug
场景:在用户通过支付通道支付完成返回时,发现我收到的处理数据记录中有两条同样的数据记录,
也就是同一笔钱,我数据库中记为了两条一样的记录。
tornado端代码
from tornado import gen
from tornado.concurrent import run_on_executor
class processNetPay(BaseHandler):
'''处理指定订单,指定支付请求,返回处理结果
' 返回包含订单信息与用户信息体
'''
@tornado.web.asynchronous
@gen.coroutine
def post(self):
...other code....
db_session = self.get_db_session()
jsonResponse = yield self.query_netpay_order_state(db_session, netpay_id)
@run_on_executor
def query_netpay_order_state(self, db_session, netpay_id):
....
with distributedlock(str("sync_netpay_%s" % netpay_id)):#分布式锁
add NetPayRecord to db
db_session.commit()
排除:一开始以为我没有使用分布式锁,或者没有在分布式锁内完成数据库的commit
但检查代码后,发现该提交的也提交了,该锁的也锁的了,不存在基本逻辑问题呀,怎么会在
NetPayRecord中产生了两条一样的记录呢?
解决:最后通过各项日志,及查看sqlalchemy源码后,发现db_session=self.get_db_session()需要写在锁内才行,
具体原因不表
记一个python+sqlalchemy+tornado的一个高并发下,产生重复记录的bug的更多相关文章
- 使用一个Python脚本来运行一个简单的Django项目
创建视图 Django是一个模型-模板-视图(model-template-view,MTV)框架. 视图部分通常检查看HTTP给出的请求和查询或者结构,这些信息是发送到表示层的数据. 我们在 hel ...
- 请写一个python逻辑,计算一个文件中的大写字母数量
import os os.chdir(r'C:\Users\Administrator\Desktop')#os.chdir切换到指定目录 with open('a.txt') as today: c ...
- 第一个Python程序(全面)
说明:该篇博客是博主一字一码编写的,实属不易,请尊重原创,谢谢大家! 一.Windows系统 1.编写Python程序方式之Sublime文本编辑器: 1>打开sublime,创建hello.p ...
- python笔记:#002#第一个python程序
第一个 Python 程序 目标 第一个 HelloPython 程序 Python 2.x 与 3.x 版本简介 执行 Python 程序的三种方式 解释器 -- python / python ...
- 人生苦短之---第一个Python程序
第一个 Python 程序 目标 第一个 HelloPython 程序 Python 2.x 与 3.x 版本简介 执行 Python 程序的三种方式 解释器 —— python / python ...
- PDNN: 深度学习的一个Python工具箱
PDNN: 深度学习的一个Python工具箱 PDNN是一个在Theano环境下开发出来的一个Python深度学习工具箱.它由苗亚杰(Yajie Miao)原创.现在仍然在不断努力去丰富它的功能和扩展 ...
- MSSQL高并发下生成连续不重复的订单号
一.确定需求 只要做过开发的基本上都有做过订单,只要做过订单的基本上都要涉及生成订单号,可能项目订单号生成规则都不一样,但是大多数规则都是连续增长. 所以假如给你一个这样的需求,在高并发下,以天为单位 ...
- python 包多熟悉一个干活就轻松点
包管理 管理包和依赖的工具. pip – Python 包和依赖关系管理工具. pip-tools – 保证 Python 包依赖关系更新的一组工具. conda – 跨平台,Python 二进制包管 ...
- 3.第一个python程序
学习任何一门语言的第一步,首先要写个'hello world',这算是程序员的一个传统.但在写之前,还有注意几个问题. 首先,python是一门脚本语言,而脚本语言的特点就是:我们写的代码会先由解释器 ...
随机推荐
- JQuery基础教程:事件(上)
在页面加载后执行任务 之前我们已经知道了$(document).ready()是jQuery基于页面加载执行任务的一种主要方式,但是要知道原生的window.onload事件也可以实现相同的 ...
- List集合分组
var ArticleList = new Services.Data.SearchService().GetArticleBaseList(ref param); IEnumerable<IG ...
- Integer cache
View.findViewById采用深度遍历,找到第一个匹配的控件 Integer Cache public static void testIntegerCache() { Class cache ...
- NOIP 2005 过河
过河 Time Limit: 1000MS Memory Limit: 65536K 题目描述 在河上有一座独木桥,一只青蛙想沿着独木桥从河的一侧跳到另一侧.在桥上有一些石子,青蛙很讨厌踩在这些石 ...
- 关于Android studio 相对 eclipse 优点
优点:说法一 1.Google推出的,这个是它的最大优势,Android Stuido是Google推出,专门为Android"量身订做"的 2.速度更快,Eclipse的启动速度 ...
- C语言-删除重复字符
//实现对一个字符串的删除重复的字符,并输出删除后的字符串,(如从”testroadeasy”中输出”tesroady”) Action(){ char *str="testroade ...
- SICP 换零钱的迭代版本
看到换零钱方式统计这里, 书中给出了递归的实现但没有给出迭代版本说要留给读者作为挑战, 既然说是作为挑战那肯定是能解决的,在想了一天无果之后最终在别人博客的帮助下终于实现了迭代的版本...也算是经历坎 ...
- Oracle对表解锁的操作
1.查出被锁的表 SELECT lpad(' ',decode(l.xidusn ,0,3,0))||l.oracle_username User_name, o.owner,o.object_na ...
- C++: std::string 与 Unicode 结合
一旦知道 TCHAR 和_T 是如何工作的,那么这个问题很简单.基本思想是 TCHAR 要么是char,要么是 wchar_t,这取决于_UNICODE 的值: // abridged from tc ...
- 序列化和反序列化,异步调用web/wcf/函数
//xml序列化 public static string Seria(DataSet ds) { XmlSerializer serializer = new XmlSerializer(typeo ...