PostgreSQL实战之事务与并发控制(二)

目录

1 PostgreSQL的事务隔离级别

1.1 查看和设置数据库的事务隔离级别

1.2 修改全局的事务隔离级别

1.3 查看当前会话的事务隔离级别

1.4 设置当前会话的事务隔离级别

1.5 设置当前事务的事务隔离级别


1 PostgreSQL的事务隔离级别

        尽管不同的数据库系统中事务隔离的实现不同,但都会遵循SQL标准中“不同事务隔离级别必须避免哪一种读现象发生”的约定。SQL标准中Read Uncommitted的事务隔离级别是允许脏读的,其本意应该是数据库管理系统在这一事务隔离级别能够支持非阻塞的读,即常说的写不阻塞读,但PostgreSQL默认就提供了非阻塞读,因此在PostgreSQL内部只实现了三种不同的隔离级别,PostgreSQL 的Read Uncommitted模式的行为和ReadCommitted相同,并且PostgreSQL的Repeatable Read实现不允许幻读。而SQL标准定义的四种隔离级别只定义了哪种现象不能发生,描述了每种隔离级别必须提供的最小保护,但是没有定义哪种现象必须发生,这是SQL标准特别允许的。在PostgreSQL中,依然可以使用四种标准事务隔离级别中的任意一种,但是要理解PostgreSQL的事务隔离级别有别于其他数据库隔离级别的定义。除此以外,这里还引入了一个新的数据冲突问题:序列化异常。序列化异常是指成功提交的一组事务的执行结果与这些事务按照串行执行方式的执行结果不一致。下面演示一个序列化异常的例子,按照从上到下的顺序分别执行T1和T2,如下所示:

PostgreSQL实战之事务与并发控制(二)_第1张图片

         在上面的例子中,事务T1开始时查询出id=1的数据,事务T2在事务T1提交之前对数据做了更新操作,并且在事务T1提交之前提交成功;当事务T1提交时,如果按照先执行T2再执行T1的顺序执行,事务T1在事务开始时查询到的数据应该是事务T2提交之后的结果: ival=10,但由于事务T1是可重复读的,当它进行UPDATE时,事务T1读到的数据却是它开始时读到的数据: ival=1 ;这时就发生了序列化异常的现象。Serializable 与Repeatable Read在PostgreSQL里是基本一样的,除了Serializable不允许序列化异常。

PostgreSQL实战之事务与并发控制(二)_第2张图片

        在上面的例子中,事务T1在tbl_mvcc表中第一次查询id大于3并且小于10的数据,得到两行数据,这时事务T2在表中插入了一条id等于6的数据,这条数据正好满足事务T1的WHERE条件中,id大于3并且小于10的查询条件,事务T1再次查询时,与第一次查询的结果相同,说明没有出现幻读现象。其他事务隔离级别对读现象的影响这里不再演示,有兴趣的读者可以自行实验。

1.1 查看和设置数据库的事务隔离级别

PostgreSQL默认的事务隔离级别是Read Committed。查看全局事务隔离级别的代码如下所示:

mydb=# SELECT name, setting FROM pg_settings WHERE name = 'default_transaction_isolation';
name                          |            setting
------------------------------------------------
default_transaction_isolation | repeatable read
( l row)
或:
mydb=# SELECT current_setting ('default_transaction_isolation') ;
    current_setting
--------------------
    repeatable read
(1 row)

1.2 修改全局的事务隔离级别

方法1:通过修改postgresql.conf文件中的default_transaction_isolation参数修改全局事务隔离级别,修改之后reload实例使之生效;
方法2:通过ALTER SYSTEM命令修改全局事务隔离级别:

mydb=# ALTER SYSTEM SET default_transaction_isolation To 'REPEATABLE READ';
ALTER SYSTEM
mydb=# SELECT pg_reload_conf ( );
    pg_reload_conf
--------------
    t
(1 row )
mydb=# SELECT current_setting ('transaction_isolation') ;
    current_setting
--------------
    repeatable read
(1 row)

1.3 查看当前会话的事务隔离级别

查看当前会话的事务隔离级别的代码如下所示:

mydb=# SHOw transaction_isolation;
    transaction_isolation
--------------
    read committed
(1 row)
或:
mydb=# SELECT current_setting ('transaction_isolation') ;
    current_setting
---------------
    read committed
(1 row)

1.4 设置当前会话的事务隔离级别

设置当前会话的事务隔离级别的代码如下所示:

mydb=# SET SESSTON CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL READ UNCOMMITED;
SET
mydb=# SHow transaction_isolation ;
    transaction_isolation
---------------
    read uncommitted
(1 row)

1.5 设置当前事务的事务隔离级别

在启动事务的同时设置事务隔离级别,如下所示:

mydb=# START TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
STARTTRANSACTION
. ..
. ..
mydb=# END;COMMIT
或:
mydb=# BEGIN ISOLATION LEVEL READ UNCOMMITTED READ WRITE;
...
...
...
mydb=# END/COMMIT/ROLLBACK;
START TRANSACTION和 BEGIN都是开启一个事务,具有相同的功能。

你可能感兴趣的:(postgresql,数据库,mysql)