Oracle   发布时间:2022-05-17  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了Oracle中的Phantom Read异常和PostgreSQL不会回滚事务大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
我注意到Oracle和Postgresql中都出现了以下情况.

考虑到我们有以下数据库架构:

create table post (
    ID int8 not null,Title varchar(255),version int4 not null,primary key (ID));    

create table post_comment (
    ID int8 not null,revIEw varchar(255),post_ID int8,primary key (ID));

alter table post_comment 
    add constraint FKna4y825fdc5hw8aow65ijexm0 
    foreign key (post_ID) references post;

有以下数据:

insert into post (Title,version,ID) values ('Transactions',1);
insert into post_comment (post_ID,revIEw,ID) 
    values (1,'Post comment 1',459,0);
insert into post_comment (post_ID,'Post comment 2',537,'Post comment 3',689,2);

如果我打开两个单独的sql控制台并执行以下语句:

TX1: BEGIN TRANSACTION ISolATION LEVEL SERIAliZABLE;

TX2: BEGIN TRANSACTION ISolATION LEVEL SERIAliZABLE;

TX1: SELECT COUNT(*) FROM post_comment where post_ID = 1;

TX1: > 3

TX1: UPDATE post_comment SET version = 100 WHERE post_ID = 1;

TX2: INSERT INTO post_comment (post_ID,ID) VALUES (1,'Phantom',1000);

TX2: COMMIT;

TX1: SELECT COUNT(*) FROM post_comment where post_ID = 1;

TX1: > 3

TX1: COMMIT;

TX3: SELECT * from post_comment;

     > 0;"Post comment 0";100;1
       1;"Post comment 1";100;1
       2;"Post comment 2";100;1
       1000;"Phantom";0;1

正如预期的那样,SERIAliZABLE隔离级别保留了TX1事务开始时的快照数据,TX1只能看到3个post_comment记录.

由于Oracle和Postgresql中的MVCC模型,TX2允许插入新记录并提交.

为什么允许TX1提交?因为这是一个幻像读取异常,我期待看到TX1将回滚“序列化失败异常”或类似的东西.

Postgresql和Oracle中的MVCC Serializable模型是否仅提供快照隔离保证但没有幻像读取异常检测?

UPDATE

我甚至更改了Tx1以发出UPDATE语句,该语句更改属于同一帖子的所有post_comment记录的版本列.

这样,Tx2创建一个新记录,并且Tx1将在不知道已添加满足UPDATE过滤条件的新记录的情况下提交.

实际上,在Postgresql上使其失败的唯一方法是在插入幻像记录之前在Tx2中执行以下COUNT查询:

Tx2: SELECT COUNT(*) FROM post_comment where post_ID = 1 and version = 0

TX2: INSERT INTO post_comment (post_ID,1000);

TX2: COMMIT;

然后Tx1将回滚:

org.postgresql.util.PsqlException: ERROR: Could not serialize access due to read/write dependencIEs among transactions
  Detail: Reason code: Canceled on IDentification as a pivot,during conflict out checking.
  Hint: The transaction might succeed if retrIEd.

写入偏斜异常预防机制很可能检测到此更改并回滚事务.

有趣的是,Oracle似乎并没有被这种异常所困扰,因此Tx1只是成功提交.由于Oracle不会阻止写入偏差的发生,因此Tx1提交juts很好.

顺便说一下,你可以自己运行所有这些例子,因为它们是在GitHub.

你观察到的不是幻读.那就是如果第二次发出查询时会出现一个新行(幻像出现意外).

您可以通过SERIAliZABLE隔离保护Oracle和Postgresql中的幻像读取.

Oracle和Postgresql之间的区别在于,Oracle中的SERIAliZABLE隔离级别仅提供快照隔离(这足以防止幻像出现),而在Postgresql中它将保证真正的可序列化(即,始终存在SQL语句的序列化,导致相同的结果).如果你想在Oracle和Postgresql中获得相同的东西,请在Postgresql中使用REPEAtable READ隔离.

大佬总结

以上是大佬教程为你收集整理的Oracle中的Phantom Read异常和PostgreSQL不会回滚事务全部内容,希望文章能够帮你解决Oracle中的Phantom Read异常和PostgreSQL不会回滚事务所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。
标签: