.前言為什麼要特別指出sqlite的多線程呢?因為建立一個sqlite串連只能給建立這個串連的線程使用,按照串連池的一般做法,先初始化幾條串連conn放到池裡,顯然不行(別的線程用不了)。如果換一種策略,在第一次使用串連時,才由線程建立串連,然後映射到線程推到池裡,在串連使用前先驗證串連是否可用--這是一種不錯的實現。
下面,是簡單實現,不涉及池~~,有時間在實現。
- 首先,定義一個類,操作某資料庫test表的增.刪.查,命名為testDao,哦,no!這名命名太狗血了吧。
import threadingimport os,sqlite3class Dao(object): ''' 資料持久化處理類 ''' def __init__(self,path,name='',*args,**kwargs): ''' 初始化工作... ''' self.lock = threading.RLock() #鎖 self.name = name self.path = path #資料庫連接參數 db_path = self.path[:self.path.rfind(os.sep)] if os.path.exists(db_path): os.makedirs(db_path) def get_conn(self): ''' 建立串連,為什麼不能設定為執行個體成員?自己想想,-- ''' conn = sqlite3.connect(self.path) return conn def conn_close(self,conn=None): ''' 操作完,關掉串連 ''' conn.close() def save(self,obj,conn=None): ''' 儲存資料 ''' cu = conn.cursor() cu.execute(obj.to_insert_sql())
- 定義資料庫連接相關的攔截器.在func調用前串連資料庫,func調用結束提高事務並關閉串連.
def conn_trans(func): ''' 資料庫連接相關的攔截器.在func調用前串連資料庫,func調用結束提高事務並關閉串連. ''' def connection(self,*args,**kwargs): self.lock.acquire() conn = self.get_conn() kwargs['conn'] = conn rs = func(self,*args,**kwargs) self.conn_close(conn) self.lock.release() return rs return connection
- 使用攔截器,攔截save方法
@conn_trans() def save(self,obj,conn=None): ''' 儲存資料 ''' cu = conn.cursor() cu.execute(obj.to_insert_sql())