Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

数据库读锁的优化的思路 #7

Open
moshengrenzenme opened this issue Dec 13, 2019 · 2 comments
Open

数据库读锁的优化的思路 #7

moshengrenzenme opened this issue Dec 13, 2019 · 2 comments

Comments

@moshengrenzenme
Copy link

在dbmanager里有很多在读取的时候加上了线程锁,感觉可以把锁去掉,让读取更快,但是这样的话应该就需要把在初始化里的self.cursor = self.connect.cursor()去掉,变成cursor=self.connect.cursor(),放到每个方法里,让他变成私有变量,这样就不会串了,这只是我的猜测,不知道能不能,当然,update是需要加锁的,insert可以考虑一下能不能也去除,让数据库操作更快,不用在线程里等待锁,因为连读都要加锁的话就感觉怪怪的,请指教

@wenbo607
Copy link
Collaborator

之前考虑过解开读sqlite的线程锁,但可能是sqlite的文件级访问原因,多线程访问会概率性出现文件游标报错,概率低但经测试多次反馈确实会出现并导致异常,才重新加上的线程锁(可以看看sqlite多线程访问使用的相关文档,实际sqlite只有不被多个线程同时使用才是安全的),确实存在问题是connect定义为self,还一个问题没设计成单列,这都是遗留问题之前没时间去重新整理,下个版本开发会在数据库访问这块发力,重新规范整理,初步打算是单列多线程带线程锁访问,感谢!

@moshengrenzenme
Copy link
Author

moshengrenzenme commented Dec 15, 2019

之前考虑过解开读sqlite的线程锁,但可能是sqlite的文件级访问原因,多线程访问会概率性出现文件游标报错,概率低但经测试多次反馈确实会出现并导致异常,才重新加上的线程锁(可以看看sqlite多线程访问使用的相关文档,实际sqlite只有不被多个线程同时使用才是安全的),确实存在问题是connect定义为self,还一个问题没设计成单列,这都是遗留问题之前没时间去重新整理,下个版本开发会在数据库访问这块发力,重新规范整理,初步打算是单列多线程带线程锁访问,感谢!

我写了两个脚本,测试了一下,在单例模式下读可以不用线程锁,但是更新和插入是必须用线程锁的
脚本如下
dbmanager.py

#!/usr/bin/env python3 #coding=utf-8 import sqlite3 import threading lock=threading.Lock() db_path="/root/.cache/uksc/uksc.db" class DbManager(object): def __init__(self): self.connect = sqlite3.connect(db_path,check_same_thread=False) def run(self,id): # try: # lock.acquire() cursor = self.connect.cursor() cursor.execute('select * from software where id='+id) print(cursor.fetchall(),'\n') cursor.close() # finally: # lock.release() def close(self): self.connect.close() def insert(self): try: lock.acquire() cursor=self.connect.cursor() cursor.execute('insert into software (app_name)values(\'测试\')') self.connect.commit() cursor.close() finally: lock.release() DBManager=DbManager()

dbTest.py

#!/usr/bin/env python3 #coding=utf-8 import threading from dbmanager import DBManager def loop(x,y): for i in range(x,y): DBManager.run(str(i)) def loop2(x,y): DBManager.insert() threadList=[] for i in [(8,15),(16,20),(21,30),(31,40),(41,50),(51,60),(61,70)]: threadList.append(threading.Thread(target=loop,args=i)) for j in range(50): threadList.append(threading.Thread(target=loop2,args=i)) for x in threadList: x.start()
测试过程中没有发现错误,并且插入和查询都没问题,没有发生数据错乱

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants