您好,登錄后才能下訂單哦!
當需要定時修改數(shù)據(jù)庫時,一般我們都選擇起一個定時進程去改庫。如果將這種定時任務寫入業(yè)務中,寫成一個接口呢,定時進程顯得有些不太合適?如果需要定時修改100次數(shù)據(jù)庫,常規(guī)做法會啟動100個進程,雖然這種進程非常輕量級,但還是會感覺不爽。實際上我們可以使用threading.Timer創(chuàng)建相應的線程來執(zhí)行改庫操作,思路也比較簡單。
1.傳入執(zhí)行改庫操作的時間update_time,用update_time和當前時間相減法,得到距離改庫操作還有多少時間time_delay。求兩個標準時間格式字符串的時間差可以使用datetime.datetime.strptime()來格式化時間,格式化后的時間可以直接相減法,對結(jié)果執(zhí)行.seconds()就可以轉(zhuǎn)化成秒
2.將改庫操作封裝成方法update(),然后將update和時間差傳入threading.Timer創(chuàng)建的線程,用法為threading.Timer(interval, function, args=[], kwargs={})創(chuàng)建線程實例,interval為延遲執(zhí)行的時間,單位是秒,然后,start()執(zhí)行。Timer是非阻塞的,可以創(chuàng)建出多個線程互不影響。
代碼如下
#!/usr/bin/env python3 # -*- coding: utf-8 -*- from model import Table from handler.base_handler import BaseHandler from threading import Timer import datetime class TimeHandler(BaseHandler): def do_action(self): update_time = "2018-04-07 18:00:00" ads_id = "test_1" t_online = datetime.datetime.strptime(update_time, '%Y-%m-%d %H:%M:%S') now = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S') t_now = datetime.datetime.strptime(now, '%Y-%m-%d %H:%M:%S') time_delay = (t_online - t_now).seconds t1 = Timer(time_delay, self.update, (ads_id, )) t1.start() self.result = "success" return def update(self, ads_id): self.db.dsp.query(Table).filter(Table.ads_id == ads_id).update({Table.is_del: 0}) self.db.dsp.commit()
可以將update_time改為前端傳入的參數(shù),就可以在該時間執(zhí)行改庫操作了。當時遇到了一個小坑,就是改庫操作沒有生效,原因是沒加最后一行的commit()。本來改庫的commit生效是寫在基類BaseHandler重的,但是這里的update()在Timer線程中執(zhí)行,屬于異步操作,需要在線程中執(zhí)行commit()使改動生效。
這種借助Timer定時執(zhí)行的方法比傳統(tǒng)的定時進程更輕量,也更簡單,但是也有著明顯的缺點。當服務關(guān)閉時,所有的定時線程也就隨著主進程一起銷毀,所有線程都能成功執(zhí)行的前提條件是服務必須穩(wěn)定,不能重啟。如果想要重啟服務,就需要想辦法將未完成的任務落盤(比如寫到數(shù)據(jù)庫中),然后啟動服務時讀取之前未完成的任務重新創(chuàng)建定時線程。
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持億速云。
免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。