LT和ET模式
数据库连接池SQLAlchemy中多线程安全的问题
1、数据库模块model.py
from sqlalchemy.orm import scoped_session
from sqlalchemy.orm import sessionmaker
session_factory = sessionmaker(bind=some_engine)
Session = scoped_session(session_factory)
2、业务模块thread.py
import threading
from model import Session class User(Base):
__tablename__ = 'users'
id = Column(Integer, primary_key=True)
name = Column(String(20))
fullname = Column(String(20))
password = Column(String(20))
age = Column(Integer) class MyThread(threading.Thread): def __init__(self, threadName):
super(MyThread, self).__init__()
self.name = threading.current_thread().name def run(self):
session = Session() #每个线程都可以直接使用数据库模块定义的Session,执行时,每一个session都相当于一个connection
session.query(User).all()
user = User(name="hawk-%s"%self.name, fullname="xxxx",password="xxxx",age=10)
session.add(user)
time.sleep(1)
if self.name == "thread-9":
session.commit()
Session.remove() if __name__ == "__main__":
arr = []
for i in xrange(10):
arr.append(MyThread('thread-%s' % i))
for i in arr:
i.start()
for i in arr:
i.join()
错误示范:
class MyThread(threading.Thread):
def __init__(self, threadName):
super(MyThread, self).__init__()
self.session = Session() #错误!
self.name = threading.current_thread().name
def run(self):
self.session.query(User).all()
user = User(name="hawk-%s"%self.name, fullname="xxxx",password="xxxx",age=10)
self.session.add(user)
time.sleep(1)
if self.name == "thread-9":
self.session.commit()
Session.remove()
错误解析:
看了SQLAlchemy之后源码发现,Session() 返回的是一个threading.local()对象的成员变量,threading.local()对象只有在线程内部才能实现线程隔离,因此只能放在run()函数里,而不能作为类成员变量。
如果按照错误示例来运行,所有线程其实公用了一个session,没有做到线程隔离,session.commit()操作会互相影响,我们原本只想将thread-9中的数据插入,结果会发现,所有线程中的数据全部被插入。
如何避免使用SQLAlchemy使用连接池
在使用 create_engine创建引擎时,如果默认不指定连接池设置的话,一般情况下,SQLAlchemy会使用一个 QueuePool绑定在新创建的引擎上。并附上合适的连接池参数。
在以默认的方法create_engine时(如下),就会创建一个带连接池的引擎。
engine = create_engine('postgresql://postgres@127.0.0.1/dbname')
在这种情况下,当你使用了session后就算显式地调用session.close(),也不能把连接关闭。连接会由QueuePool连接池进行管理并复用。
这种特性在一般情况下并不会有问题,不过当数据库服务器因为一些原因进行了重启的话。最初保持的数据库连接就失效了。随后进行的session.query()等方法就会抛出异常导致程序出错。
如果想禁用SQLAlchemy提供的数据库连接池,只需要在调用create_engine是指定连接池为NullPool,SQLAlchemy就会在执行session.close()后立刻断开数据库连接。当然,如果session对象被析构但是没有被调用session.close(),则数据库连接不会被断开,直到程序终止。
下面的代码就可以避免SQLAlchemy使用连接池:
#!/usr/bin/env python
#-*- coding: utf-8 -*- from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy.pool import NullPool engine = create_engine('postgresql://postgres@127.0.0.1/dbname',
poolclass=NullPool)
Session = sessionmaker(bind=engine)
session = Session()
usr_obj_list = session.query(UsrObj).all()
print usr_obj_list[0].id
session.close()
https://blog.csdn.net/daijiguo/article/details/79486294
https://blog.csdn.net/weiwangchao_/article/details/80185009
参考:
https://www.cnblogs.com/1a2a/p/8278698.html
http://blog.csdn.net/kikaylee/article/details/53232920
LT和ET模式的更多相关文章
- 【原】谈谈对Objective-C中代理模式的误解
[原]谈谈对Objective-C中代理模式的误解 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 这篇文章主要是对代理模式和委托模式进行了对比,个人认为Objective ...
- 彻底理解AC多模式匹配算法
(本文尤其适合遍览网上的讲解而仍百思不得姐的同学) 一.原理 AC自动机首先将模式组记录为Trie字典树的形式,以节点表示不同状态,边上标以字母表中的字符,表示状态的转移.根节点状态记为0状态,表示起 ...
- 制作类似ThinkPHP框架中的PATHINFO模式功能
一.PATHINFO功能简述 搞PHP的都知道ThinkPHP是一个免费开源的轻量级PHP框架,虽说轻量但它的功能却很强大.这也是我接触学习的第一个框架.TP框架中的URL默认模式即是PathInfo ...
- MVVM模式解析和在WPF中的实现(六) 用依赖注入的方式配置ViewModel并注册消息
MVVM模式解析和在WPF中的实现(六) 用依赖注入的方式配置ViewModel并注册消息 系列目录: MVVM模式解析和在WPF中的实现(一)MVVM模式简介 MVVM模式解析和在WPF中的实现(二 ...
- MVVM模式解析和在WPF中的实现(五)View和ViewModel的通信
MVVM模式解析和在WPF中的实现(五) View和ViewModel的通信 系列目录: MVVM模式解析和在WPF中的实现(一)MVVM模式简介 MVVM模式解析和在WPF中的实现(二)数据绑定 M ...
- MVVM模式解析和在WPF中的实现(三)命令绑定
MVVM模式解析和在WPF中的实现(三) 命令绑定 系列目录: MVVM模式解析和在WPF中的实现(一)MVVM模式简介 MVVM模式解析和在WPF中的实现(二)数据绑定 MVVM模式解析和在WPF中 ...
- MVVM模式和在WPF中的实现(二)数据绑定
MVVM模式解析和在WPF中的实现(二) 数据绑定 系列目录: MVVM模式解析和在WPF中的实现(一)MVVM模式简介 MVVM模式解析和在WPF中的实现(二)数据绑定 MVVM模式解析和在WPF中 ...
- MVVM模式和在WPF中的实现(一)MVVM模式简介
MVVM模式解析和在WPF中的实现(一) MVVM模式简介 系列目录: MVVM模式解析和在WPF中的实现(一)MVVM模式简介 MVVM模式解析和在WPF中的实现(二)数据绑定 MVVM模式解析和在 ...
- Microservice架构模式简介
在2014年,Sam Newman,Martin Fowler在ThoughtWorks的一位同事,出版了一本新书<Building Microservices>.该书描述了如何按照Mic ...
- 工厂方法模式——创建型模式02
1. 简单工厂模式 在介绍工厂方法模式之前,先介绍一下简单工厂模式.虽然简单工厂模式不属于GoF 23种设计模式,但通常将它作为学习其他工厂模式的入门,并且在实际开发中使用的也较为频繁. (1 ...
随机推荐
- Voice Commands (VCD) Cortana 微软小娜示例
Cortana 样品 您可以创建自定义功能Cortana使用Cortana技能装备或遗留的声音命令(VCD)平台. 在这里,你可以找到相关的样品: Cortana技能装备 目前Cortana技巧是建立 ...
- ffmpeg & mplayer & vlc 手册(转)
如何基于FFMPEG和SDL写一个少于1000行代码的视频播放器 http://blog.sina.com.cn/s/blog_51396f890100nd91.html http://lanhy20 ...
- JDK中枚举的底层实现
前提 上一篇文章复习介绍了JDK中注解的底层实现,跟注解一样比较常用,但是底层实现比较神秘的还有枚举类型.趁着国庆假期的最后两天,把JDK中枚举的底层实现也进行一次探究. 通过例子查找本质 在探究JD ...
- 使用 Tmux 强化终端功能
来自 tmux是一个优秀的终端复用软件,类似GNU Screen,但来自于OpenBSD,采用BSD授权.使用它最直观的好处就是通过一个终端登录远程主机并运行tmux后,在其中可以开启多个控制台而无需 ...
- 实战:sqlserver 日常检查脚本
--sqlserver 日常检查脚本 print '----------------------------' print ' 0.sqlserver all information ' print ...
- js 给json添加新的字段,或者添加一组数据,在JS数组指定位置删除、插入、替换元素
JS定义了一个json数据var test={name:"name",age:"12"};需要给test再添加一个字段,需要什么办法,可以让test的值为{na ...
- Okhttp实用封装
概述 对okhttp的get,put,delete,post请求简单封装,减少了不必要的冗余代码 详细 代码下载:http://www.demodashi.com/demo/11101.html 在自 ...
- conn
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding= ...
- Python-线程的生命周期
线程的生命周期 所谓的xx生命周期,其实就是某对象的包含产生和销毁的一张状态图.线程的生命周期如下图所示: 各状态的说明如下: New新建.新创建的线程经过初始化后,进入Runnable状态. Run ...
- IHttpHandler的那些事
写在前面 从上家公司离职,在家休息,闲着无聊,觉得还是有必要将IHttpHanlder的内容,做一个总结.发现在写demo的过程中,总觉得有点生疏了,项目中很少使用自定义的类来实现该接口.当然,一般处 ...