前言

这是实际生产环境中遇到的一个问题,前端业务有如下报错:

could not serialize access due to read/write dependencies among transactions
Detail: Reason code: Canceled on coinflict out to pivot as a pivot 27892139, during read.

串行化隔离级别的含义

可串行化隔离级别保证了数据库中事务是按照顺序串行执行,而非并行。数据库可以防止所有可能的竞争条件。

串行化隔离级别可能会遇到的阻塞情况

创建测试数据
create table idx (id int,ci character varying );
create index on idx(id);
insert into idx select generate_series(1,10000);
TEST=# insert into idx select generate_series(1,10000);
INSERT 0 10000
修改 KINGBASE.CONF中
default_transaction_isolation = 'SERIALIZABLE'
重启数据库

1.Read触发报错,事务执行时间顺序如下表:

时间点 T1 T2 T3
t1 begin;
t2 select * from idx where id = 1;
t3 begin;
t4 update idx set ci='x' where id =1;
t5 begin;
t6 update idx set ci='x' where id=1000;
t7 commit;
t8 select * from idx where id = 1000;

T2在执行select时候有如下报错

TEST=# select * from idx where id = 1000;
ERROR: could not serialize access due to read/write dependencies among transactions
DETAIL: Reason code: Canceled on conflict out to pivot 1771, during read.
HINT: The transaction might succeed if retried.

报错原因是T2事务在t4时间点还没结束,然后开启T3事务,而当T3事务结束以后,T2事务再执行select查询就违反了串行隔离级别的定义。

当一个事务处于可串行化级别, 一个select查询只能看到在事务开始之前提交的数据而永远看不到未提交的数据或事务执行中其他并行事务提交的修改。

2.Write触发报错,事务执行时间顺序如下表:

时间点 T1 T2 T3
t1 begin;
t2 select * from idx where id = 1;
t3 begin;
t4 select * from idx where id = 1000;
t5 begin;
t6 update idx set ci='x' where id =1000;
t7 commit;
t8 update idx set ci ='x' where id =1;

T2在执行update时候有如下报错

TEST=# update idx set ci ='x' where id =1;
ERROR: could not serialize access due to read/write dependencies among transactions
DETAIL: Reason code: Canceled on identification as a pivot, during write.
HINT: The transaction might succeed if retried.

从表格的时间线我们可以看出,对于serialize串行隔离级别,我们必须老老实实一个个事务按顺序进行,如不然就会出现如上报错。

3.Commit触发报错,事务执行时间顺序如下表:

时间点 T1 T2
t1 begin;
t2 select * from idx where id =1;
t3 update idx set ci = 'x' where id =1000;
t4 begin;
t5 select * from idx where id = 1000;
t6 update idx set ci ='x' where id =1;
t7 commit;
t8 commit;

T1在执行commit时候有如下报错

TEST=# commit;

ERROR: could not serialize access due to read/write dependencies among transactions

DETAIL: Reason code: Canceled on identification as a pivot, during commit attempt.

HINT: The transaction might succeed if retried.

总结

一个可串行化的事务在可串行化事务开始之后不能更改被其他事务更改过的行。

当应用收到这样的错误信息时,它应该退出当前的事务然后从头开始进行整个事务。请注意只有更新事务才需要报错重试,只读事务从来没有串行化冲突。

可串行化事务隔离级别必须保证每个事务都看到一个完整的数据库的视图。如果并行更新令数据库不能维持串行执行的样子,那么应用必须准备重试事务。

KingbaseES 串行化隔离级别引起的阻塞分析的更多相关文章

  1. 关于ORACLE的串行化隔离级别--来自ORACLE概念手册

    为了描述同时执行的多个事务如何实现数据一致性,数据库研究人员定义了被 称为串行化处理(serializability)的事务隔离模型(transaction  isolation model).当所有 ...

  2. Oracle 6 - 锁和闩 - transaction的可串行化

    本文主要内容 1.transaction的可串行化 2.数据库并发带来的问题, dirty read, Nonrepeatable reads, Phantoms幻读 3.隔离级别和2中的问题 4. ...

  3. 【Java EE 学习 72 下】【数据采集系统第四天】【移动/复制页分析】【使用串行化技术实现深度复制】

    一.移动.复制页的逻辑实现 移动.复制页的功能是在设计调查页面的时候需要实现的功能.规则是如果在同一个调查中的话就是移动,如果是在不同调查中的就是复制. 无论是移动还是复制,都需要注意一个问题,那就是 ...

  4. PHP面向对象04_串行化

    oop04复习 2014-9-3 10:48:45 要点: --1.克隆对象 --2.__toString( ) --3. __call( ) --4.自动加载类 --5.对象串行化 1.克隆对象以及 ...

  5. 【PHP面向对象(OOP)编程入门教程】22.把对象串行化serialize()方法,__sleep()方法,__wakeup()方法

    有时候需要把一个对象在网络上传输,为了方便传输,可以把整个对象转化为二进制串,等到达另一端时,再还原为原来的对象,这个过程称之为串行化(也叫序列化), 就像我们现在想把一辆汽车通过轮船运到美国去,因为 ...

  6. VC++ chap13 文档与串行化

    Lesson 13 文档与串行化 13.1使用CArchive类对文件进行读写操作 //让对象数据持久性的过程称之为串行化,或者序列化 void CGraphicView::OnFileWrite() ...

  7. Java 对象的串行化(Serialization)

    1.什么是串行化 对象的寿命通常随着生成该对象的程序的终止而终止.有时候,可能需要将对象的状态保存下来,在需要时再将对象恢复.我们把对象的这种能记录自己的状态以便将来再生的能力.叫作对象的持续性(pe ...

  8. 【性能诊断】四、单功能场景的性能分析(RedGate,找到同一个客户端的并发请求被串行化问题)

    问题描述: 客户端js连续发起两个异步http请求,请求地址相同,但参数不同:POST http://*.*.*.*/*****/webservice/RESTFulWebService/RESTFu ...

  9. PHP面向对象(OOP):把对象串行化serialize()方法,__sleep()方法,__wakeup()方法

    有时候需要把一个对象在网络上传输,为了方便传输,可以把整个对象转化为二进制串,等到达另一端时,再还原为原来的对象,这个过程称之为串行化(也叫序列化), 就像我们现在想把一辆汽车通过轮船运到美国去,因为 ...

  10. php中对象的串行化

    我们大家有知道PHP串行化可以把变量包括对象,转化成连续bytes数据,你可以将串行化后的变量存在一个文件里或在网络上传输,然后再反串行化还原为原来的数据.文章这里就PHP串行化为大家详细的介绍.你在 ...

随机推荐

  1. 【Unity3D】血条(HP)

    1 需求实现 ​ 人机交互Input 中实现了通过键盘控制坦克运动,通过鼠标控制坦克发射炮弹,本文将在此基础上,增加血条(HP)功能.炮弹命中后,HP 值会减少,因此需要应用到 刚体组件Rigidbo ...

  2. 基于keras的胶囊网络(CapsNet)

    1 简介 胶囊网络(CapsNet)由 Hinton 于2017年10月在<Dynamic Routing Between Capsules>中提出,目的在于解决 CNN 只能提取特征,而 ...

  3. Windows SDK 之 mciSendString最后一个参数

    这里在这里先附上mciSendString的函数原型: MCIERROR mciSendString( LPCTSTR lpszCommand, LPTSTR lpszReturnString, UI ...

  4. RunnerGo低代码测试体验

    RunnerGo是基于go语言自研的一款企业级全栈式测试平台,采用Apache-2.0 license开源协议,涵盖接口测试.性能测试.UI测试和项目管理等功能,并独创"拖拉拽"的 ...

  5. ADVMP 三代壳(vmp加固)原理分析(执行流程)

    由于在加壳时插入了System.loadLibrary("advmp");,看一下JNI_OnLoad JNIEXPORT jint JNICALL JNI_OnLoad(Java ...

  6. 异步aioredis连接时报错TypeError: duplicate base class TimeoutError问题

    版本 python3.11版本,aioredis 2.0.1版本,redis 7.x版本 redis.conf配置文件 daemonize yes bind 0.0.0.0 port 6379 pro ...

  7. django学习第三天---django模板渲染,过滤器,反向循环 reversed,自定义标签和过滤器,模板继承

    django模板渲染 模板渲染,模板指的就是html文件,渲染指的就是字符串替换,将模板中的特殊符号替换成相关数据 基本语法 {{ 变量 }} {% 逻辑 %} 变量使用 示例 Views.py文件 ...

  8. logback中使用MDC自定义日志输出格式

    logback-MDC 相当于自定义日志格式输出 写在过滤器中 示例: try { Context context = createContext(request, response); proces ...

  9. 【Azure Redis 缓存】如何使得Azure Redis可以仅从内网访问? Config 及 Timeout参数配置

    问题描述 问题一:Redis服务,如何可以做到仅允许特定的子网内的服务器进行访问? 问题二:Redis服务,timeout和keepalive的设置是怎样的?是否可以配置成timeout 0? 问题三 ...

  10. Java 数组对象 小测试

    1 package com.bytezero.bank; 2 /** 3 * 4 * @Description 5 * @author Bytezero·zhenglei! Email:4204982 ...