Odoo | multithreading | 多线程

Odoo能自己写多线程程序吗? Why not ?

简介

从Odoo自身的机制上来讲,它的每一个连接都是一个单线程作业的过程。

Odoo在连接池(ConnectionPool)中加入了线程锁threading.Lock(),监测DB连接数与线程建立连接数量。

当线程池中的DB连接数大于DB连接阈值,就会报错线程池满了,线程池满后新的客户端访问会被拒绝,后台任务或者新的线程任务也会失败(可能会导致程序不执行,更严重的会导致数据丢失)。

虽然框架有各种各样的限制,那我们能否在自己的代码中实现多线程代码,用以提高程序执行效率呢?当然可以 看例子:

实例代码

import odoo
import threading
class ...
    @api.model
    def main_func_ytc(self):
    	userids = [1,2,3]
        # 最大占用10个线程 防止线程池占满(DB连接数默认64,除过系统基本占用10-20个,我们自定义5-10个线程基本都在范围内)
        max_connections = 10
        pool_sema = threading.BoundedSemaphore(max_connections)
        
        print('这是主线程:{}'.format(threading.current_thread().name))
        thread_list=[]
        for userid in userids:
            pool_sema.acquire() # 线程加锁
            # pool_sema 用于控制程序执行线程总量
            m = threading.Thread(target=self.sub_func, args=(pool_sema, userid))
            thread_list.append(m)
        for m in thread_list:
        	# m.setDaemon(True) # 目前并不需要使用守护线程
            m.start()
        #for m in thread_list:
        #    m.join()

    @api.model
    def sub_func_ytc(self, pool_sema, userid):
        with api.Environment.manage():
        	# 新线程中不能用老的游标,因为主线程不是守护线程,没有join的话,可能游标就关闭了,
        	# 所以要新建连接和游标,这里的self.pool.cursor() 其实是先创建连接 _cnx,再创建游标 _obj, 切记返回值并不是游标,而是Cursor对象的实例。
            new_cr = self.pool.cursor()
            self = self.with_env(self.env(cr=new_cr))
			
			# START 方法功能代码内容(ORM/SQL均可)#
			self.env['xxx'].search([])
            sql = "insert into XXX() values ();"
            self._cr.execute(sql)
            # END   方法功能代码内容             #
            
            # 提交事务 self._cr._cnx.commit() 也行
            # 反正这里的commit是conn.commit(),或者说是_cnx.commit()
            self._cr.commit() 
            
            # 关闭游标(基操)
            new_cr.close() 
            
            # 关闭连接 _cnx = conn :
            # 如果不手动关闭连接 你可以查看SQL连接数 系统不会默认关 时间长了会导致前面简介中提到的DB连接数超出
            # select * from pg_stat_activity order by pid desc;
            new_cr._cnx.close() 
            pool_sema.release() # 线程解锁

说明

基本的描述都在代码注释中说明了,你只需要针对性的调整:

  1. 函数名称与参数参数
  2. 线程数 max_connections
  3. 方法功能代码内容

结论

我在多线程下的项目开发中所能体会到的是:
需要调用108次企业微信接口的数据获取,正常流程需要38s
使用10线程跑批的方式,仅需要2s

本文章基于Odoo12测试, 如有问题欢迎交流。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

比特本特

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值