1. 程式人生 > >python多執行緒操作資料庫問題

python多執行緒操作資料庫問題

python多執行緒併發操作資料庫,會存在連結資料庫超時、資料庫連線丟失、資料庫操作超時等問題。

解決方法:使用資料庫連線池,並且每次操作都從資料庫連線池獲取資料庫操作控制代碼,操作完關閉連線返回資料庫連線池。

*連線資料庫需要設定charset = 'utf8', use_unicode = True,不然會報中文亂碼問題

*網上說解決python多執行緒併發操作資料庫問題,連線時使用self.conn.ping(True)(檢查並保持長連線),但是我這邊親測無法解決,建議還是使用資料庫連線池

python多執行緒程式碼:

import threading

class MyThread(threading.Thread):

	def __init__(self, name, count, exec_object):
		threading.Thread.__init__(self)
		self.name = name
		self.count = count
		self.exec_object = exec_object

	def run(self):
		while self.count >= 0:
			count = count - 1
			self.exec_object.execFunc(count)

thread1 = MyThread('MyThread1', 3, ExecObject())
thread2 = MyThread('MyThread2', 5, ExecObject())
thread1.start()
thread2.start()
thread1.join() # join方法 執行完thread1的方法才繼續主執行緒
thread2.join() # join方法 執行完thread2的方法才繼續主執行緒
# 執行順序 併發執行thread1 thread2,thread1和thread2執行完成才繼續執行主執行緒

# ExecObject類是自定義資料庫操作的業務邏輯類
# 

########join方法詳解########
thread1 = MyThread('MyThread1', 3, ExecObject())
thread2 = MyThread('MyThread2', 5, ExecObject())
thread1.start()
thread1.join() # join方法 執行完thread1的方法才繼續主執行緒
thread2.start()
thread2.join() # join方法 執行完thread2的方法才繼續主執行緒
# 執行順序 先執行thread1,執行完thread1再執行thread2,執行完thread2才繼續執行主執行緒

mysql資料庫連線池程式碼:

import MySQLdb
from DBUtils.PooledDB import PooledDB

class MySQL:

	host = 'localhost'
	user = 'root'
	port = 3306
	pasword = ''
	db = 'testDB'
	charset = 'utf8'

	pool = None
	limit_count = 3 # 最低預啟動資料庫連線數量

	def __init__(self):
		self.pool = PooledDB(MySQLdb, self.limit_count, host = self.host, user = self.user, passwd = self.pasword, db = self.db,
			port = self.port, charset = self.charset, use_unicode = True)

	def select(self, sql):
		conn = self.pool.connection()
		cursor = conn.cursor()
		cursor.execute(sql)
		result = cursor.fetchall()
		cursor.close()
		conn.close()
		return result

	def insert(self, table, sql):
		conn = self.pool.connection()
		cursor = conn.cursor()
		try:
			cursor.execute(sql)
			conn.commit()
			return {'result':True, 'id':int(cursor.lastrowid)}
		except Exception as err:
			conn.rollback()
			return {'result':False, 'err':err}
		finally:
			cursor.close()
			conn.close()