odoo手动提交事务问题探索

背景:

在做项目时,发现数据库中几百条数据的修改时间都是相同的。寻找其中原因,在代码层面为了避免大数据量放在一次修改数据,特意做了分页查询,每一页执行一次更新方法,所有数据放在循环里处理。

理论上就能实现数据的分批处理,更新时调用odoo模型中默认的write方法。

原因:

在循环中加断点,每次执行write方法之后,数据应该被修改,但是数据库中数据并未发生变化,而是等所有数据执行完毕才会统一变化。

其中原因就是单独执行write方法时,只提交了修改命令,但是未提交事务,所以数据库没有发生更新,

在源码中找到提交事务的代码,debug,发现循环过程中并未执行提交,只有在最后返回的时候提交一次事务。就造成了上面说的所有数据的修改时间相同。

问题思考:

如果循环的数据量无论多大,都一次提交,如果其中一条数据发生异常,所有数据都将回滚,这是我们担心的问题。再有,如果数据量百万之巨,那么还是一次提交事务会不会因为数据量太大造成其他问题。

 

起初我的想法很简单,既然write方法不能自动提交事务,那么就手动提交,self.env.cr.commit() 在数据库连接的脚本中,创建的游标执行sql之后都是手动提交事务的,

 

 

果然,加上手动提交事务之后,每次循环结束,都能看到数据库中对应的数据发生了变化。

 

后来在odoo社区发现其中有一篇帖子视手动提交事务为洪水猛兽,因为手动提交事务没办法确保出现问题能准确回滚,也就是没办法保证数据的安全性和准确性。

甚至说出了无论你在哪里看到了self.env.cr.commit() 这行代码,都要删了它!

 

 

他说不能手动提交事务,因为不能保证数据出现问题的回滚,我们还考虑到一点,就是手动提交事务的时候,会不会把其他并行事务的未完成的操作一并提交了。

 

能不能手动提交事务,还要看并行的事务之间是什么隔离级别。

数据库并行事务时,不同的隔离级别会出现不同的读取问题,脏读、幻读、不可重复读。

脏读:事务b读到事务a修改的数据,但是a还未提交事务。

不可重复读:在事务a中运行同一条sql两次,第二次结果是被事务b修改过的数据。

幻读:事务a查询时没有发现数据,事务b插入数据,事务a插入数据发现主键冲突,再次查询扔未查到数据

介绍一下并行事务的四种隔离级别。

read uncommitted 读未提交:一个事务还未提交,变更就能被别的事务看到。   

read commited 读已提交:一个事务提交后,变更才能被别的事务看到。 

repeatable read 可重复读:一个事务执行过程中看到的数据,总是跟这个事务启动时看到的数据一致。

seriallizable 可串行化:读写都会加锁,当读写锁冲突时,后访问的事务必须等前一个事务执行完毕才能执行。

 

odoo采用的是后两种 可重复读和可串行化

 

 

确保事务并行过程中的数据安全。既然事务之间的安全级别高,那在一个事务中的提交只与该事务有关。

 

大事务处理

回到提交事务的问题,查阅资料发现有人对数据库做过大数据量的压力测试,事务提交越频繁效率越低

 

 

但是大事务确实也会带来很多问题。比如锁定太多的数据,造成阻塞和锁超时;回滚时间长;执行时间长容易造成主从延迟。

所以取中间合适的数据量提交事务提升效率同时降低风险。

 

postgresql自动提交事务默认开启状态。

关于postgresql的自动提交事务测试。

 

 

关闭自动提交事务

 

 

 

 

插入数据之后回滚能取消上一步操作,并且使用连接工具看不到数据,说明事务并未提交。

未提交的事务,修改的数据无法让其他事务看到,其实还是未修改成功的状态。

 

 

而Postgresql默认是自动提交的,只不过在pgadmain上执行一条sql语句时,执行完毕就会提交。

而当执行多个sql语句时,只有当全部执行完毕,第一个sql语句才会自动提交。

若第一个sql语句时update语句,sql全部执行完毕后,数据表才会进行update的提交,数据表才会改变,否则,数据表是不会改变的。

连续的sql语句会放在一起执行,也就是作为一个sql语句提交,从前到后依次执行。中间遇到错误所有修改一并回滚。

刚好就是背景里遇到的问题。

结合对odoo并行事务隔离级别的了解。加上自动提交事务的特性,手动提交事务确实能避免大事务的提交,同时效率可能有所降低,

但是和请求第三方api的时间相比,微不足道。

对于手动提交事务的风险,是修改不可逆,一旦提交发现问题回滚不了。

在程序中,错误的修改数据,如果不是抛出异常,也无法获取,最后还是一并提交,不能回滚。

关于是否能手动提交,我们还要在不同的使用场景中做实验才能确定是否会发生风险。

 

posted @ 2023-02-17 14:31  木_糖  阅读(388)  评论(0编辑  收藏  举报