postgresql事务介绍

postgresql事务介绍

事务的隔离级别目前有4种,分别是读未提交,读已提交,可重复读,串行化。

postgres=# \h begin
Command: BEGIN
Description: start a transaction block
Syntax:
BEGIN [ WORK | TRANSACTION ] [ transaction_mode [, …] ]
where transaction_mode is one of:
ISOLATION LEVEL { SERIALIZABLE | REPEATABLE READ | READ COMMITTED | READ UNCOMMITTED }
READ WRITE | READ ONLY
[ NOT ] DEFERRABLE

  • 读未提交,表示可以读到其他会话未提交的数据。(postgresql不支持)

  • 读已提交,表示可以读到其他会话已提交的数据。以下介绍读已提交。

    1、进入pg中
    /opt/sequoiasql/bin/psql – p 5432 foo

    2、创建一张表为test2,插入一条记录
    foo=# insert into test2 values (1,’pppp’);
    INSERT 0 1

    3、在会话1中打开事务进行查询
    foo=# begin;
    BEGIN
    foo=# select * from test2;
    id | name
    —-+——
    1 | pppp
    (1 row)

    4、在会话2中打开事务进行更新
    foo=# begin;
    BEGIN
    foo=# update test2 set name =’kk’;
    UPDATE 1

    5、此时在会话2中还没有关闭事务,在会话1中进行查询
    foo=# select * from test2;
    id | name
    —-+——
    1 | pppp
    (1 row)

    6、发现会话1中的记录并没有进行改变。当提交会话2中的事务,在会话1中进行查询值已经改变
    foo=# select * from test2;
    id | name
    —-+——
    1 | kk
    (1 row)

  • 可重复读,表示在一个事务中,执行同一条SQL,读到的是同样的数据(即使被读的数据可能已经被其他会话修改并提交)。

    1、在会话1中打开可重复读事务,进行查询
    foo=# begin transaction isolation level repeatable read ;
    BEGIN
    foo=# select * from test2;
    id | name
    —-+——
    1 | kk
    (1 row)

    2、在会话2中进行更新操作
    foo=# update test2 set name =’hh’;
    UPDATE 1

    3、在会话1中进行查询,发现会话1中的记录因为会话2的提交而变化
    foo=# select * from test2;
    id | name
    —-+——
    1 | kk
    (1 row)

    4、在会话1中提交事务之后进行查询
    foo=# end;
    COMMIT
    foo=# select * from test2;
    id | name
    —-+——
    1 | hh
    (1 row)

  • 串行化,表示并行事务模拟串行执行,违反串行执行规则的事务,将回滚。

    1、在会话 1中打开事务
    foo=# begin transaction isolation level serializable ;

    2、在会话2中打开事务
    foo=# begin transaction isolation level serializable ;

    3、在会话1中进行插入操作
    foo=# select * from test2;
    id | name
    —-+——
    1 | hh
    (1 row)
    foo=# insert into test2 select * from test2;
    INSERT 0 1
    foo=# select * from test2;
    id | name
    —-+——
    1 | hh
    1 | hh
    (2 rows)

    4、在会话2中进行插入操作
    foo=# select * from test2;
    id | name
    —-+——
    1 | hh
    (1 row)
    foo=#
    foo=# insert into test2 select * from test2;
    INSERT 0 1

    5、提交会话1中的事务,能够正常提交,进行查询能够查到插入的记录
    foo=# end;
    COMMIT
    foo=# select * from test2;
    id | name
    —-+——
    1 | hh
    1 | hh
    (2 rows)

    6、当提交会话2的事务时会报错
    FATAL: could not serialize access due to read/write dependencies among
    transactions
    DETAIL: Reason code: Canceled on identification as a pivot, during commit attempt.
    HINT: The transaction might succeed if retried.
    FATAL: could not serialize access due to read/write dependencies among transactions
    DETAIL: Reason code: Canceled on identification as a pivot, during commit attempt.
    HINT: The transaction might succeed if retried.
    The connection to the server was lost. Attempting reset: Succeeded.

猜你喜欢

转载自blog.csdn.net/u014439239/article/details/78216417