论Postgres的“已提交的而且 xmin’比当前事务的…
2018-06-22 01:00:58来源:未知 阅读 ()
- 事务已经提交(commit);
- 提交时插入记录的xmin 小于 当前current_txid(事务id)。
- 事务隔离级别READ COMMITTED
--session A 事务id为1844;
postgres=# begin;
BEGIN
postgres=# select txid_current();
txid_current
--------------
1844
--session B 事务id为1845;并在插入一条记录在lottu05表(未提交)
postgres=# begin;
BEGIN
postgres=# select txid_current();
txid_current
--------------
1845
postgres=# insert into lottu05 values (1001,'lottu');
INSERT 0 1
--在session A/B查看记录; session A读不到记录; session B可以读到记录。
postgres=# select * from lottu05;
id | name
----+------
(0 rows)
--在session B提交插入的记录;在查看session A是否可以看到记录。
postgres=# select xmin,* from lottu05;
xmin | id | name
------+------+-------
1845 | 1001 | lottu
--表明session A(当前事务为ID:1844)可以读 插入记录事务id为1845 已经提交的记录。
--总结: 事务隔离级别为读已提交(READ COMMITTED)就是读已经提交的记录。
由此可见,对读已提交隔离级别而言"已提交的而且 xmin’比当前事务的XID小的记录对当前事务才是可见的"是不正确的。
而网上的解释:也是必要不充分条件。那该如何诠释这说话呢?请看下文讲解
是根据当前postgres系统的当前事务ID相比;目前系统下一个事务ID为1846
-- 我们现在看下当前postgres系统 下一个事务id
[postgres@localhost ~]$ pg_controldata |grep NextXID
Latest checkpoint's NextXID: 0/1846
--意思是说这条记录后面开启会话从事务id:1846是可见的。不充分的是事务ID:1844也可以读到该记录。
--然而这句话来源何处;我想是有依据的。接下来我们做一个实验。模拟postgrs穿越到过去。
--session C 现在插入1002-1008条记录;结果如下:
postgres=# select xmin,id,name from lottu05;
xmin | id | name
------+------+---------
1845 | 1001 | lottu
1846 | 1002 | lottu02
1847 | 1003 | lottu03
1848 | 1004 | lottu04
1849 | 1005 | lottu05
1850 | 1006 | lottu06
1851 | 1007 | lottu07
1852 | 1008 | lottu08
--我们现在使用将数据库postgres回到 txid 为1849。注意:该动作不建议操作;
[postgres@localhost ~]$ pg_stop
waiting for server to shut down.......... done
server stopped
[postgres@localhost ~]$ pg_resetxlog -x 1849 $PGDATA
Transaction log reset
[postgres@localhost ~]$ pg_start
server starting
[postgres@localhost ~]$ psql
psql (9.5.0)
Type "help" for help.
postgres=# select xmin,id,name from lottu05;
xmin | id | name
------+------+---------
1845 | 1001 | lottu
1846 | 1002 | lottu02
1847 | 1003 | lottu03
1848 | 1004 | lottu04
1849 | 1005 | lottu05
--可以看到上面的xmin:(1850-1852)是不可见的。
--等数据库的事务ID超过1852;这些数据可以展示出来。
postgres=# select txid_current();
txid_current
--------------
1850
postgres=# select txid_current();
txid_current
--------------
1851
postgres=# select txid_current();
txid_current
--------------
1852
postgres=# select xmin,id,name from lottu05;
xmin | id | name
------+------+---------
1845 | 1001 | lottu
1846 | 1002 | lottu02
1847 | 1003 | lottu03
1848 | 1004 | lottu04
1849 | 1005 | lottu05
1850 | 1006 | lottu06
1851 | 1007 | lottu07
1852 | 1008 | lottu08
--从这个实验看来 确实是需要满足网上所说的两个条件。上面也提过;该操作不建议操作。设想;当前时代若可以穿越到历史上各个时代;那历史不乱套了吗?同理如此。
所以说对隔离级别为READ COMMITTED而言;如同它字面解释一样;只要记录COMMITTED;就可以读到。
注意:
--1.该操作不等同 oracle的flashback操作;虽然回到了历史;历史上已经发生的还是会发生。
--2.该操作并不能做数据恢复操作。若对数据做删除进行恢复;可以参考--http://www.cnblogs.com/lottu/p/5761885.html
- 事务隔离级别:REPEATABLE READ
事务隔离级别:REPEATABLE READ;是不是如同它而言呢?接下来拭目以待吧。
--开启SESSION A; ctid为1857。
postgres=# truncate table lottu05;
TRUNCATE TABLE
postgres=# begin;
BEGIN
postgres=# select txid_current();
txid_current
--------------
1857
--开启session B;隔离级别为REPEATABLE READ。事务id为:1858
postgres=# begin ISOLATION LEVEL REPEATABLE READ;
BEGIN
postgres=# select txid_current();
txid_current
--------------
1858
--在session A插入 10条记录并提交
postgres=# insert into lottu05 select generate_series(1001,1010),'lottu'||generate_series(1,10);
INSERT 0 10
postgres=# commit;
COMMIT
--在session B查看是否可以读到记录
postgres=# select * from lottu05;
id | name
----+------
(0 rows)
--结果表明session B 读不到 已经提交且 事务ID:1857比session B的事务ID为1858要小的记录。
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
- 力扣:超级回文数 2019-07-24
- 向后台提交数据:cookie,secure_cookie, 2019-02-17
- form表单提交方式 2018-10-03
- 用Django连接数据库 2018-09-29
- PostgreSQL数据加载工具之pg_bulkload 2018-08-02
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash
