成都创新互联网站制作重庆分公司

PostgreSQL存储过程中怎么利用BEGIN块处理事务

PostgreSQL存储过程中怎么利用BEGIN块处理事务,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。

站在用户的角度思考问题,与客户深入沟通,找到华容网站设计与华容网站推广的解决方案,凭借多年的经验,让设计与互联网技术结合,创造个性化、用户体验好的作品,建站类型包括:成都做网站、网站设计、企业官网、英文网站、手机端网站、网站推广、域名注册网站空间、企业邮箱。业务覆盖华容地区。

1、用BEGIN块模拟

随便建个表:

CREATE TABLE a(col1 int);

存储过程如下:

CREATE OR REPLACE FUNCTION ins_t() RETURNS void
AS $$
BEGIN
  INSERT INTO a VALUES(100);
  BEGIN
    INSERT INTO a VALUES(200);
    RAISE 'any error';
  EXCEPTION
    WHEN others THEN
      null;
  END;
END;
$$ LANGUAGE plpgsql;

测试:

flying=# SELECT ins_t();                                                                                  ins_t
-------

(1 row)

flying=# SELECT * FROM a;
 col1
------
  100
(1 row)

可以看到,内嵌BEGIN块中的INSERT操作并没有生效。

2、PL/pgSQL如何实现

块定义在pl_gram.y中,有兴趣可以自己去看,块的执行代码位于 src/pl/plpgsql/src/pl_exec.c

static int
exec_stmt_block(PLpgSQL_execstate *estate, PLpgSQL_stmt_block *block)
{
...

	if (block->exceptions)
	{
...
		BeginInternalSubTransaction(NULL);
...
		PG_TRY();
...
		PG_CATCH();
...
			RollbackAndReleaseCurrentSubTransaction();
...

只有当块定义有EXCEPTION部分,才会出现创建子事务的动作,否则(它对应的else分支内)只会当做普通语句处理。抛出例外时,就把这个子事务会滚掉。

而如果不抛出例外,而是WARNING或者NOTICE之类,也不会引起它的回滚,尝试一下就知道。PG怎么知道要不要回滚,关键在PG_TRY,这个说起来话长,暂时了解到这里足够。

3、没有EXCEPTION处理会怎样

去掉例外处理部分

CREATE OR REPLACE FUNCTION ins_t() RETURNS void
AS $$
BEGIN
  INSERT INTO a VALUES(100);
  BEGIN
    INSERT INTO a VALUES(200);
    RAISE 'any error';
  END;
END;
$$ LANGUAGE plpgsql;

结果什么都没有,因为它没有启用子事务,所以会全部回滚。

flying=# select ins_t();
ERROR:  any error
CONTEXT:  PL/pgSQL function ins_t() line 6 at RAISE
flying=# select * from a;
 col1
------
(0 rows)

flying=#

4、神奇的PG_TRY和PG_CATCH

它们用到的是sigsetjmp,PG中很多地方用到它,了解这个可能需要一定的汇编语言知识,也需要了解错误抛出机制,有机会再详细讲。

看完上述内容,你们掌握PostgreSQL存储过程中怎么利用BEGIN块处理事务的方法了吗?如果还想学到更多技能或想了解更多相关内容,欢迎关注创新互联行业资讯频道,感谢各位的阅读!


网站标题:PostgreSQL存储过程中怎么利用BEGIN块处理事务
分享URL:http://cxhlcq.com/article/ghjgcd.html

其他资讯

在线咨询

微信咨询

电话咨询

028-86922220(工作日)

18980820575(7×24)

提交需求

返回顶部