除非写在exception中, 那会回滚前面的非exception部分, 执行exception部分, 同样无法达到以上目的.
所以不能单纯依靠PostgreSQL函数来解决以上问题. 需要在外部声明with hold游标, 在函数中使用这个游标. 这样是可以的.
以下均为autocommit模式. 即自动提交
1. 创建以下函数替换以上函数
2. 在会话中声明游标,
3. 通过多次调用函数来实现, 每次调用为一次事务.
digoal=# select f_batch(5,'c1');
NOTICE: do some thing , rec:(pg_statistic,11,10818,0,10,0,12550,0,15,387,15,2840,0,t,f,p,r,26,0,f,f,f,f,f,t,1674,1,{postgres=arwdDxt/postgres},)
NOTICE: do some thing , rec:(pg_type,11,71,0,10,0,0,0,8,334,8,0,0,t,f,p,r,30,0,t,f,f,f,f,t,1674,1,{=r/postgres},)
NOTICE: do some thing , rec:(pg_toast_2619,99,11050,0,10,0,12552,0,2,10,2,0,2841,t,f,p,t,3,0,f,f,f,f,f,t,1674,1,,)
NOTICE: do some thing , rec:(pg_toast_2619_index,99,0,0,10,403,12554,0,2,10,0,0,0,f,f,p,i,2,0,f,f,f,f,f,t,0,0,,)
NOTICE: do some thing , rec:(pg_authid_rolname_index,11,0,0,10,403,0,1664,2,1,0,0,0,f,t,p,i,1,0,f,f,f,f,f,t,0,0,,)
NOTICE: do some thing , rec:(pg_authid_oid_index,11,0,0,10,403,0,1664,2,1,0,0,0,f,t,p,i,1,0,f,f,f,f,f,t,0,0,,)
NOTICE: reach batch limit.
f_batch
---------
(1 row)
digoal=# select f_batch(5,'c1');
NOTICE: do some thing , rec:(pg_attribute_relid_attnam_index,11,0,0,10,403,0,0,16,2281,0,0,0,f,f,p,i,2,0,f,f,f,f,f,t,0,0,,)
NOTICE: do some thing , rec:(pg_attribute_relid_attnum_index,11,0,0,10,403,0,0,11,2281,0,0,0,f,f,p,i,2,0,f,f,f,f,f,t,0,0,,)
NOTICE: do some thing , rec:(pg_toast_1255,99,11047,0,10,0,0,0,0,0,0,0,2837,t,f,p,t,3,0,f,f,f,f,f,t,1674,1,,)
NOTICE: do some thing , rec:(pg_toast_1255_index,99,0,0,10,403,0,0,1,0,0,0,0,f,f,p,i,2,0,f,f,f,f,f,t,0,0,,)
NOTICE: do some thing , rec:(pg_toast_2604,99,11044,0,10,0,12586,0,0,0,0,0,2831,t,f,p,t,3,0,f,f,f,f,f,t,1674,1,,)
NOTICE: do some thing , rec:(pg_toast_2604_index,99,0,0,10,403,12588,0,1,0,0,0,0,f,f,p,i,2,0,f,f,f,f,f,t,0,0,,)
NOTICE: reach batch limit.
f_batch
---------
(1 row)
digoal=# select f_batch(500,'c1');
中间省略
NOTICE: do some thing , rec:(pg_toast_12392_index,99,0,0,10,403,12782,0,1,0,0,0,0,f,f,p,i,2,0,f,f,f,f,f,t,0,0,,)
NOTICE: do some thing , rec:(sql_packages,12269,12408,0,10,0,12793,0,1,10,1,12409,0,f,f,p,r,5,0,f,f,f,f,f,t,1674,1,"{postgres=arwdDxt/postgres,=r/postgres}",)
NOTICE: do some thing , rec:(pg_toast_12412_index,99,0,0,10,403,12802,0,1,0,0,0,0,f,f,p,i,2,0,f,f,f,f,f,t,0,0,,)
NOTICE: cursor is empty. close it
f_batch
---------
(1 row)
游标已关闭.
使用这种方法需要注意关闭游标, 因为其他会话看不到这个游标, 也无法去关闭这个游标. 只有声明这个游标的会话可以关闭它.
游标长时间不关闭会影响vacuum回收垃圾. 这个PostgreSQL的mvcc机制有关. 例如 :