回答

收藏

MVCC数据库在交易中是否看到插入的行?

技术问答 技术问答 205 人阅读 | 0 人回复 | 2023-09-12

MVCC数据库隔离模式是否允许正在进行的事务查看其他事务的插入(和提交)?
! }& O- k. w8 A. `4 G9 z0 |例如,给定:, n* B: l! p: G, c
表 names[id BIGINT NOT NULL,name VARCHAR(30),PRIMARY KEY(id),UNIQUE(name)]0 o" k: g! f9 G/ y( T
交易T1和T2,
" M* E2 p* W* v, oT1: open transaction3 e5 w+ ~0 K! l4 Y0 ?+ h
T2: open transaction1 s" q3 y" b9 [- ?5 R- _, T9 S1 \; J
T1: select * from names;6 H8 |! C1 ?% W' H* g
                insert into names(name) values(“John”);7 p% F$ V  d$ d  J5 ^
                // do something& k5 ?0 M! C5 q  U8 d) n+ U
                commit;) F) Z; L, p# |; l. W, d. Q9 m
T2: select * from names;
9 C' k5 r  X' S; T8 `                insert into names values(“John”);
5 L% a3 C' H' ]: U9 L3 F" f7 f                // do something9 A/ X0 g5 ^5 G) z$ d5 d0 p
                commit;, ]9 t/ f+ B: D+ L
T什么时候第一次知道新行?select时间?在insert时间?还是在某个地方commit时间?0 M5 K' P0 W( v- h) Z' p6 L% `5 X
                                                                : W9 j. l' v& K3 |# z+ s
    解决方案:                                                               
" H" B, l' K0 v5 H                                                                答案确实取决于服务器的实现和唯一的约束是否被标记为延迟。. Z5 u* ]# R+ d8 B$ w5 s
我没有测试过其他数据库,但是在PostgreSQL(作为最著名的开源MVCC复制设置在我的测试中T2失败INSERT。但是,T2不能用来查看T做出任何改变SELECT。) s7 F, Z7 G9 N$ y0 O0 M
我几乎同时在两个独立的地方SQL以下句子在连接中执行:
" O" P) h' t9 d2 u$ t" L$ M' qBEGIN;SELECT * FROM names;SELECT pg_sleep(10);INSERT INTO names values('john');SELECT pg_sleep(10);COMMIT;一个成功,另一个失败在10秒后,有:7 n; `4 l: z. s* \  A3 u
ERROR:  duplicate key value violates unique constraint "names_pkey"DETAIL:  Key (name)=(john) already exists.因为文档说:
% k5 c& B. z, l' r6 ~如果未提交的事务已插入冲突行,可能的插入程序必须等待查看事务是否已提交。如果回滚,就没有冲突。如果提交但没有再次删除冲突,则表示有独特的冲突。4 N5 A! w' {! m/ p4 p$ D$ ~
但是,如果将唯一性约束标记为可延迟,则将是COMMIT检查唯一性:" I6 O# U; D. D
如果可以延迟唯一性约束,那么就会有额外的复杂性:我们需要能够插入索引条目,但将任何违反唯一性的错误推迟到句子结束或更晚。
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则