MySQL 的乐观并发控制Optimistic concurrency control

默认情况下, MySQL的Innodb事务隔离级别是重复读 repeatable read,

SELECT @@GLOBAL.tx_isolation, @@tx_isolation;REPEATABLE-READ    REPEATABLE-READ

进行以下测试, 同时开两个session, S1 和 S2, 都将autocommit关掉

set autocommit=0;

测试使用的是一张简单的表, 只有一行数据

CREATE TABLE `t1` (
  `v1` tinyint(2) NOT NULL DEFAULT ‘0‘,
  `v2` tinyint(2) NOT NULL DEFAULT ‘0‘,
  `version` mediumint(8) NOT NULL DEFAULT ‘0‘,
  PRIMARY KEY (`v1`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

row: 1    1    0

01 - S1 执行 select * from t1; 看到1, 1, 0
02 - S2 执行 select * from t1; 看到1, 1, 0
03 - S2 执行 update t1 set v2=2, version=version+1 where v1=1 and version=0; (Affected rows: 1)
04 - S2 执行 select * from t1; 看到1, 2, 1
05 - S1 执行 select * from t1; 看到1, 1, 0 - 无变化
06 - S1 执行 update t1 set v2=2, version=version+1 where v1=1 and version=0; 被挂起, 一直等待
07 - S2 执行 commit;  第06步的S1查询结束, 显示(Affected rows: 0)
08 - S1 执行 select * from t1; 依然看到1, 1, 0
09 - S1 执行 commit; 
10 - S1 执行 select * from t1; 看到1, 2, 1 - 这时候数据才更新

由此可以验证, 在 REPEATABLE-READ 的隔离级别下, 一个事务并不能觉察到事务外部的数据变化, 所有读取的数据自事务开始后就不变, 但是update类型的操作, 会受到事务外部数据变化的影响, 首先是如果同一行数据有外部事务未提交, 则当前操作需要排队, 其次是如果同一行数据已经被外界更改, 则update操作会受影响, 例如本例中 Affected rows: 0

由此可见, 通过形如 update t1 set v2=2, version=version+1 where v1=1 and version=0 的方式来做并发控制是可行的.

时间: 2025-01-07 10:50:40

MySQL 的乐观并发控制Optimistic concurrency control的相关文章

乐观的并发控制(optimistic concurrency control)

ES是分布式的.当document被create,update,或者delete,这个document的新版本就会冗余到cluster的其他node中.ES是异步和并发的,意味着冗余请求也是并行进行的,并且请求到达也是无次序的.因此需要一个方式保证老版本的document不能重写新版本的数据. 如上所述,当我们讨论index,get和delete请求,我们指出每个document都有一个_version号,这个号码随着document的变化而增长.ES使用这个_version保证document

继续说说spring security之并发控制(Concurrency Control)

定义,作用,说明: Concurrency Control:并发控制,主要用于避免同一用户多次登录,重复登录以及包括相关的session管理--具体官网---> 先看官网:http://docs.spring.io/autorepo/docs/spring-security/4.0.0.CI-SNAPSHOT/reference/htmlsingle/#session-mgmt 官网的并发控制已经说得比较清楚,但是偏偏有人(例如我)重写了(自定义了)验证的方法,导致了失效的问题,至此,一起说说s

MySQL: InnoDB的并发控制,锁,事务模型

一.并发控制 为啥要进行并发控制? 并发的任务对同一个临界资源进行操作,如果不采取措施,可能导致不一致,故必须进行并发控制(Concurrency Control). 技术上,通常如何进行并发控制? 通过并发控制保证数据一致性的常见手段有: 锁(Locking) 数据多版本(Multi Versioning) 二.锁 如何使用普通锁保证一致性? 普通锁,被使用最多: (1)操作数据前,锁住,实施互斥,不允许其他的并发任务操作: (2)操作完成后,释放锁,让其他任务执行: 如此这般,来保证一致性.

数据访问模式:数据并发控制(Data Concurrency Control)

1.数据并发控制(Data Concurrency Control)简介 数据并发控制(Data Concurrency Control)是用来处理在同一时刻对被持久化的业务对象进行多次修改的系统.当多个用户修改业务对象的状态并试图并发地将其持久化到数据库时,需要一种机制来确保一个用户不会对另一个并发用户的事务状态造成负面影响. 有两种形式的并发控制:乐观和悲观.乐观并发控制假设当多个用户对业务对象的状态同时进行修改时不会造成任何问题,也称为最晚修改生效(last change wins).对于

Entity Framework 乐观并发控制

一.背景 我们知道,为了防止并发而出现脏读脏写的情况,可以使用Lock语句关键字,这属于悲观并发控制的一种技术,,但在分布式站点下,锁的作用几乎不存在,因为虽然锁住了A服务器的实例对象,但B服务器上的锁是不知道的A服务器上锁的情况的,所以,面对分布式站点.单一数据库这种架构,我们可以使用EntityFramework的乐观并发控制来解决这个问题,EF对并发控制有不管控和乐观并发控制两种,默认情况是不管控,但EF不支持悲观并发. lock 确保当一个线程位于代码的临界区时,另一个线程不进入临界区.

【MySQL】乐观锁和悲观锁

最近学习了一下数据库的悲观锁和乐观锁,根据自己的理解和网上参考资料总结如下: 悲观锁介绍(百科): 悲观锁,正如其名,它指的是对数据被外界(包括本系统当前的其他事务,以及来自外部系统的事务处理)修改持保守态度,因此,在整个数据处理过程中, 将数据处于锁定状态.悲观锁的实现,往往依靠数据库提供的锁机制(也只有数据库层提供的锁机制才能真正保证数据访问的排他性,否则,即使在本系统中实现了 加锁机制,也无法保证外部系统不会修改数据). 使用场景举例:以MySQL InnoDB为例 商品goods表中有一

也谈乐观并发控制(转)

add by zhj: 本文主要谈的是乐观并发控制,虽然乐观并发控制不太适用于并发写冲突很频繁的场景下,因为这样会导致事务回滚,需要用户重试retry, 但是如果不用乐观并发控制的话,貌似也没有其它什么好的办法了,悲观锁并不能解决更新丢失的问题,比如本文中的例子,我们也可以想想Git 遇到这种情况时是怎么处理的,其实Git也会像本文一样处理.为什么说悲观锁也不能完全解决更新丢失的问题呢?我们看下面的例子,两个用户 张三,李四,他们两人可以更新同一条数据库记录,假设记录为(sex,age) = (

MySQL多版本并发控制(MVCC)

MVCC是行级锁的一个变种,但是它在很多的情况下避免了加锁操作,因此开销更低.MySQL,包括Oracle.PostgreSQL都实现了MVCC,虽然每个关系数据库实现不一样,但大都是实现了非阻塞的读操作,写操作也只锁定必要的行. MVCC的实现原理:InnoDB的MVCC的实现原理,是通过在每行记录后面保存两个隐藏的列来实现的.这两个列,一个保存了行的创建时间,一个保存行的过期时间或删除时间.MVCC实现类型都是有乐观并发控制和悲观并发控制. MVCC下的SELECT.INSERT.DELET

并行控制(concurrency control)

之前讲的都是概念,关于实际怎么防止调度读到或者写到自己不该写的东西我们其实一!点!都!没!讲!啦啦啦 实际中实现isolation这个性质的机制有两种,一种被称为TWO_PHASE LOCKING 还有一个被称为snapshot isolation,前面那个字面就很好理解,二步锁定,后面那个直接翻译被称为快照隔离.下面我们讲的是锁定. 锁定分为两种: shared,即分享锁定,这个被分享锁定所锁定的数据可以被其他的调度套上分享锁定.这个锁定的拥有者对于锁定数据的操作权限仅限于读取数据. excl