1.1 使用PostgreSQL事务

在PostgreSQL中,每一个操作都是一个事务。

SELECT
    now(),
    now();

              now              |              now
-------------------------------+-------------------------------
 2020-02-29 07:21:55.100997+00 | 2020-02-29 07:21:55.100997+00
(1 row)

now()函数返回该事务的时间。在这种情况下,SELECT语句是一个单独的事务,因此,总是返回两个相同的时间戳。

如果要让多个语句作为同一个事务的一部分,就必须使用BEGIN子句:

postgres=# BEGIN;
BEGIN


SELECT
    now();

              now
-------------------------------
 2020-02-29 07:15:06.975875+00
(1 row)


SELECT
    now();

              now
-------------------------------
 2020-02-29 07:15:06.975875+00
(1 row)


postgres=# COMMIT;
COMMIT
postgres=# BEGIN;
BEGIN


SELECT
    txid_current();

 txid_current
--------------
          697
(1 row)


SELECT
    txid_current();

 txid_current
--------------
          697
(1 row)


postgres=# COMMIT;
COMMIT

在事务内部处理错误

在PostgreSQL中,只有没有错误的事务才能被提交。

postgres=# BEGIN;
BEGIN


SELECT
    1;

 ?column?
----------
        1
(1 row)


SELECT
    1 / 0;

ERROR:  division by zero


SELECT
    1;

ERROR:  current transaction is aborted, commands ignored until end of transaction block


postgres=# COMMIT;
ROLLBACK

在一个错误出现后,即便后面的指令在语义和语法上都是正确的,也将不会再有语句被接受。这种情况下,仍然可以发出一个COMMIT。不过,PostgreSQL将回滚该事务。

使用保存点

在专业应用中,很难写出长度合理的事务而且在运行中永不出错。为了解决这一问题,可以使用SAVEPOINT

postgres=# BEGIN;
BEGIN


SELECT
    1;

 ?column?
----------
        1
(1 row)


postgres=# SAVEPOINT a;
SAVEPOINT


SELECT
    2 / 0;

ERROR:  division by zero


postgres=# ROLLBACK TO SAVEPOINT a;
ROLLBACK


SELECT
    3;

 ?column?
----------
        3
(1 row)


postgres=# COMMIT;
COMMIT

事务性DDL

在PostgreSQL中,可以在一个事务块中运行DDL(改变数据结构的命令)。在一个典型的商业系统中,在当前事务中的DDL将会被隐式地提交,但在PostgreSQL中不是这样。除去少量例外(DROP DATABSECREATE TABLESPACE/DROP TABLESPACE等),PostgreSQL中所有的DDL都是事务性的。

postgres=# BEGIN;
BEGIN


CREATE TABLE test (
    id int
);
CREATE TABLE


postgres=# \d

        List of relations
 Schema | Name | Type  |  Owner
--------+------+-------+----------
 public | test | table | postgres
(1 row)


ALTER TABLE
    test
ALTER COLUMN
    id TYPE int8;
ALTER TABLE


postgres=# \d test

     Table "public.test"
 Column |  Type  | Modifiers
--------+--------+-----------
 id     | bigint |


postgres=# ROLLBACK;
ROLLBACK


postgres=# \d

No relations found.

如果用户想要部署软件,事务性DDL特别重要。想象运行一个CMS的场景,如果发布了一个新的版本,用户将会想要升级。单独运行旧版本或者新版本可能都是可以的,但是用户不希望得到新旧版本的混合体。因此,将升级放在一个单一事务内无疑会大有益处,因为这会使升级变成一个原子操作。

psql允许用户使用i指令包括文件。它允许用户开始一个事务、载入一些文件并且在一个单一事务中执行它们。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值