论Postgres的“已提交的而且 xmin’比当前事务的XID小的记录对当前事务才是可见的”
- 事务已经提交(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要小的记录。
论Postgres的“已提交的而且 xmin’比当前事务的XID小的记录对当前事务才是可见的”的更多相关文章
- 本人为巨杉数据库(开源NoSQL)写的C#驱动,支持Linq,全部开源,已提交github
一.关于NoSQL的项目需求 这些年在做AgileEAS.NET SOA 中间件平台的推广.技术咨询服务过程之中,特别是针对我们最熟悉的医疗行业应用之中,针对大数据分析,大并发性能的需求,我们也在慢慢 ...
- SQL Server已提交读快照隔离级别的设置
如果要把SQL Server数据库事务隔离级别设置为已提交读快照隔离 如果直接运行下面的语句: ALTER Database [mydbname] SET READ_COMMITTED_SNAPSHO ...
- git修改已提交记录的注释
已提交暂存区但还未提交远端仓库 命令:git commit --amend -m 已提交远端仓库 命令:git rebase 可以参考:http://www.cnblogs.com/dudu/p/47 ...
- svn命令行修改已提交的版本备注
svn命令行修改已提交的版本备注 参考文章: stackoverflow.com/questions/304383/how-do-i-edit-a-log-message-that-i-already ...
- SQL Server 已提交读快照 测试
1. 打开数据库 已提交读快照 选项 2. 数据库 已提交读快照 模式下的测试 a) 测试表 Test b) 开启事务1,更新数据C2 = '200'(未提交) BEGIN TRAN ' WHERE ...
- TortoiseSVN 忽略文件 忽略已提交文件
主要以下两种情况: 1.首次提交就做好了忽略拦截:项目首次提交到svn服务器的时候,把该删的删了,然后设置忽略规则,就没问题了. 2.提交一段时间忽然想忽略拦截:经常碰到的,发现设置忽略规则后,没法生 ...
- git学习------>如何修改git已提交的记录中的Author和Email?
一.背景 最近搭建好GitLab后,准备陆陆续续的将之前在SVN仓库中保存的代码迁移到GitLab上,昨天顺利将三个Android组件的代码迁移到GitLab后,其他同事发现迁移是成功了,但是pull ...
- Eclipse中使用GIT将已提交到本地的文件上传至远程仓库
GIT将已提交到本地的文件上传至远程仓库: 1. 右击项目——Team——Push to Upstream,即可将已保存在本地的文件上传推至GIT远程仓库.
- 修改GIT已提交的用户名和邮箱
修改GIT已提交的用户名和邮箱 原文:https://help.github.com/en/github/using-git/changing-author-info 说明 要更改在现有提交中记录的名 ...
随机推荐
- 从show slave status 中判断mysql同步状态
slave status 中检查同步状态: 1.sql线程和io线程显示yes Slave_IO_Running: Yes Slave_SQL_Running: Yes 2. Master_Log_F ...
- 用JAVA写一个日历计划
效果图(自己需要在前台加css修饰)
- ZK dropEvent简单使用
前台(Drop.zul) <?page title="拖动测试" contentType="text/html;charset=UTF-8"?> & ...
- 自动删除Mysql备份(数组+for)
#!/bin/bash #author:V #Dispaly:auto delete mysql backup. BACKDIR=(/home/11/mysqlbackup/ /home/full/) ...
- JSONObject简介
JSONObject简介 本节摘要:之前对JSON做了一次简单的介绍,并把JSON和XML做了一个简单的比较:那么,我就在想,如果是一个json格式的字符串传到后台,需要怎么对其处理?如果前台页面需要 ...
- Read4096
Given API: int Read4096(char* buf); It reads data from a file and records the position so that the n ...
- NEC学习 ---- 布局 -三列, 左右定宽,中间自适应
---恢复内容开始--- 这个布局很牛掰, 我觉得学习价值很大. 通过这个的学习, 我发现, 能将简单的事情做好, 就距离成功不远了. 其实布局就是利用所学知识, 活用. 在没看这个之前, 发现自己的 ...
- embedded tomcat context.xml
在网络下载相关的embedded tomcat jar.也可直接在maven中检索. 在main方法中,输入以下代码: //新建tomcat实例 Tomcat tomcat = new Tomcat( ...
- Java中的virtual method
今天看jcvm的标准的 时候,看到有一个virtual method,感觉很疑惑,以前看Java的时候并没有发现有这类方法. 百度.Google了一下,才发现,Java中普通方法就是virtual m ...
- 检测PC端和移动端的方法总结(转)
正在苦逼的实习中,昨天公司让做一个页面,涉及到检测终端的问题,如果是手机设备,就跳转到指定的网页上,以前写响应式布局只要用@media screen来实现布局的差异化适应,但是现在不仅仅是布局,还要针 ...