【MogDB解读MogDB5.0.6版本中有关兼容性的一些更新
前言
MogDB于2024-03-30发布了其5.0版本的补丁版本—5.0.6,其在MogDB 5.0.5的基础上新增部分特性并修复了部分缺陷,具体内容可参考官方文档
1. MogDB 5.0.6发布说明
相信有一些伙伴和我一样对兼容性的部分感兴趣,因此本篇就针对本次更新的一些涉及到有关兼容性的东西,大概说说
涉及兼容性更新的列表
- Select自动提交
- 支持order by/group by后使用字符串常量
- 支持聚集函数进行嵌套使用
- 支持用户自主决定所有数据类型中空串是否转变为null
- 兼容PG的INSERT…ON CONFLICT语法
- 支持浮点数字符串与整型可以直接运算
- 对齐Oracle中“AUTHID CURRENT_USER”的行为
- 提高部分场景下mod函数结果的精度
- 增加alter sequence可以修改的序列属性
- 支持update/delete语句中使用return
- 支持scroll的游标
- 支持MERGE INTO语句中字段不用加表名前缀
一、Select自动提交
了解PG的开发应该比较清楚,在PG中,非自动提交的情况下,连接数据库,仅执行一个select查询语句,在不执行任何DML操作的情况下,也会使该连接处于idle in transcation状态,即该会话存在一个未完成的事务。
因此在开发中要么设置成自动提交,要么就要显式地执行commit或者rollback,才能让该连接变为idle状态。
这种设计对于基于ORACLE进行开发的应用来说,非常不友好,因为在ORACLE数据库中,一般的sql查询是感觉不到有事务的,最明显的感受就是,执行完select语句后,plsql developer的绿色commit按钮没亮起来(执行带dblink的select会亮,但不在本篇讨论范围内 ),而执行完dml语句后会亮起来。
持续占有事务其实是一种资源消耗,而且还会阻塞truncate语句的执行。为了解决这个问题,MogDB开发出了select自动提交的功能。当然这个select自动提交,并不是无论什么时候一执行select就自动commit,它其实是有很多前置条件的:
首先就是需要使用新版本的连接驱动,而且要关闭连接属性中的autocommit;其次就是需要设置GUC参数,在behavior_compat_options中添加compat_oracle_txn_control,再然后就是各种细分场景了
## 各场景下自动提交事务行为
- 单独的读命令自动提交(不含select for update/share/key share/no key update)
- 事务块内部的读命令不自动提交,需要显式提交
- 函数/存储过程内部的读命令不自动提交,函数内部只有读命令的话,执行完函数自动提交
- 单独的写命令需要显式提交(insert/update/delete/merge)
- 事务块内部的写命令不自动提交,需要显式提交
- 函数/存储过程内部的写命令不自动提交,需要显式提交
- 单独的DDL自动提交
- 事务块内部的DDL命令不自动提交,需要显式提交
- 函数/存储过程内部的DDL不自动提交,如果DDL不存在写行为,执行完函数自动提交
- 函数/存储过程内部的DDL不自动提交,如果DDL存在写行为,执行完函数需要显式提交
- 函数/存储过程内部存在子事务,不考虑子事务提交或者回滚,只看主事务是否存在写行为,如果存在写行为,需要显式提交,不存在写行为,自动提交。
- 对于特殊的DDL命令,比如explain、匿名块、execute,如果内部存在写行为,需要显式提交
- 对于单条lock命令,函数/存储过程内部的lock命令,内核会显式地放到事务块执行,需要显式提交
- 对于单条的declare cursor游标定义操作,内核会显式地放到事务块执行,需要显式提交。函数/存储过程内部的游标定义操作不会主动放到事务块执行,执行完函数自动提交。
其实核心点就是在于,通过设置数据库参数,让驱动知道不需要再自动开启事务,从而让内核可以根据场景来控制自动提交的行为(这里要注意,该功能依赖特定的驱动版本)。
当然对于各种语句是否自动提交,MogDB的5.0.6版本并未和Oracle保持完全一致,比如存储过程内的DDL如果有写操作,仍然是不自动提交的,而Oracle则是会在执行DDL的前后都自动提交一次。因为这只是"select 自动提交"这一个功能,至于DDL自动提交,可以期待后续的版本。
二、支持order by/group by后使用字符串常量
经常自己写sql的人会想,这功能有啥用啊,谁会在order by 和group by 后写无意义的非数字常量啊。但是,经常使用ORM框架的就能理解,让sql语句都固定一个格式,能减少很多开发量。
举个例子:
前台可以手动对某个查询结果按照指定的字段排序,因此生成的语句大概是
select col1,col2 from tab where col1=1 order by col2;