AttributeError: 'NoneType' object has no attribute 'read'还有AttributeError: 'NoneType' object has no attribute 'settimeout'还有TypeError: 'bool' object is not iterable等等,各类奇葩的错误。
好好的程序,前段页面同时发送了两个ajax请求,后端获取数据库数据就报错,经过不断的尝试,发现屏蔽任何一个ajax请求都没问题,只要同时发送两个就会报错,获取不到数据库数据,怀疑是数据库多线程访问加锁导致的,经上网搜索可能是以下的原因:
连接数据库用的是单例模式,访问请求使用了多线程,后台多线程共享了同一个数据库连接,但是数据库连接的每个execute前没有加上互斥锁就会报错:
AttributeError: 'NoneType' object has no attribute 'read'
错误原因:不详
尝试将数据库的单例连接修改为连接池连接,完美解决,不再
import logging
import threading
from queue import Queue, Empty
__version__ = '0.1'
__author__ = 'Chris'
logger = logging.getLogger('pymysqlpool')
__all__ = ['PoolContainer', 'PoolIsEmptyException', 'PoolIsFullException']
class PoolIsFullException(Exception):
pass
class PoolIsEmptyException(Exception):
pass
class PoolContainer(object):
"""
Pool container class: it's a pool manager with safe threading locks.
Be aware of the dead lock!!!!!!!!!!!
"""
def __init__(self, max_pool_size):
self._pool_lock = threading.RLock()
self._free_items = Queue()
# self._pool_items = list()
self._pool_items = set()
self._max_pool_size = 0
self.max_pool_size = max_pool_size
def __repr__(self):
return '<{0.__class__.__name__} {0.size})>'.format(self)
def __iter__(self):
with self._pool_lock:
return iter(self._pool_items)
def __contains__(self, item):
with self._pool_lock:
return item in self._pool_items
def __len__(self):
with self._pool_lock:
return len(self._pool_items)
def add(self, item):
"""Add a new item to the pool"""
# Duplicate item will be ignored
if item is None:
return None
if item in self:
logger.debug(
'Duplicate item found "{}", '
'current size is "{}"'.format(item, self.size))
return None
if self.pool_size >= self.max_pool_size:
raise PoolIsFullException()
self._free_items.put_nowait(item)
with self._pool_lock:
# self._pool_items.append(item)
self._pool_items.add(item)
logger.debug(
'Add item "{!r}",'
' current size is "{}"'.format(item, self.size))
def return_(self, item):
"""Return a item to the pool. Note that the item to be returned should exist in this pool"""
if item is None:
return False
if item not in self:
logger.error(
'Current pool dose not contain item: "{}"'.format(item))
return False
self._free_items.put_nowait(item)
logger.debug('Return item "{!r}", current size is "{}"'.format(item, self.size))
return True
def get(self, block=True, wait_timeout=60):
"""Block until a free item is found in `wait_timeout` seconds.
Otherwise, a `WaitTimeoutException` will be raised.
If `wait_timeout` is None, it will block forever until a free item is found.
"""
try:
item = self._free_items.get(block, timeout=wait_timeout)
except Empty:
raise PoolIsEmptyException('Cannot find any available item')
else:
logger.debug('Get item "{}",'
' current size is "{}"'.format(item, self.size))
return item
@property
def size(self):
# Return a tuple of the pool size in detail
return '<max={}, current={}, free={}>'.format(self.max_pool_size, self.pool_size, self.free_size)
@property
def max_pool_size(self):
return self._max_pool_size
@max_pool_size.setter
def max_pool_size(self, value):
if value > self._max_pool_size:
self._max_pool_size = value
@property
def pool_size(self):
return len(self)
@property
def free_size(self):
"""Not reliable as described in document of the `queue` module"""
return self._free_items.qsize()
大T笔记 » AttributeError: ‘NoneType’ object has no attribute ‘read’