首页
学习
活动
专区
圈层
工具
发布
    • 综合排序
    • 最热优先
    • 最新优先
    时间不限
  • 来自专栏DBA随笔

    innodb机制探究(二)---间隙(2)

    innodb机制探究(二)---间隙(2) 上一篇文章中,我们已经知道innodb中的间隙是对普通索引记录的间隙做的一个锁定动作,这篇文章我们分析下间隙锁在唯一索引中的应用。 也就是说,不存在gap。 再看下一个实验: ? 我们可以看到,在我们搜索age=15的时候,这条记录是不存在的,那么在session B中插入id=14的这条记录的时候,我们发现是无法插入的,产生了等待,这就说明当记录不存在的时候,唯一索引中也会产生间隙 总结一下 当字段是唯一索引或者主键的时候,间隙产生的规则如下: 1、如果查询的结果中包含这个记录,那么在另外的会话上插入该记录前后间隙的记录时,不会产生间隙 2、如果查询的结果中不包含这个记录,那么在另外的会话上插入该记录前后间隙的记录时 ,会产生间隙

    70110发布于 2019-11-06
  • 来自专栏DBA随笔

    Innodb机制探究(一)---自增(2)

    // Innodb机制探究(一)---自增(2) // 之前我们说过一篇关于MySQL的自增,但是没有系统的做测试,今天做一点测试,看看效果。 通过上面这张图我们可以看到,当我们在一个事务中进行自增列的insert操作时候,另外一个会话中又进行了插入记录的操作,在这种情况下,会发生2个奇怪的现象: 1、会话1中的自增列好像直接增加了2个值。 2、会话2中的自增列直接从2开始增加。 那么为什么表级别的,我们还能够在会话1中的事务没有结束的时候,在另外一个会话2上成功执行insert呢?不应该直接表么? 2、对于常规的insert操作,可以使用参数innodb_autoinc_lock_mode来控制是否使用表级别的,如果该参数是0,则使用表级别的auto_inc ,如果该参数是1,则使用互斥自增长机制实现主键的自增

    1.8K20发布于 2019-11-19
  • 来自专栏MySQL解决方案工程师

    InnoDB数据–第2部分“

    > 例如:一个系统可以同时包含以下与单个资源(表report的row#2)有关的 <transaction#3305, row#2 of table `report`, shared, granted > <transaction#3305, row#2 of table `report`, exclusive, granted > <transaction#3306, row#2 of table | report | S | GRANTED | | 3305 | 2 | report | X | GRANTED | | 3306 | : con1> LOCK TABLES t READ; Query OK, 0 rows affected (0.00 sec) 您可能希望事务已锁定表t,但是看不到任何: con2> SELECT 因此,我只是说这个表显示了服务器获取的,阻止了其他客户端尝试修改表: con3> insert into test.t values (10); ⌛ 将等待,您可以通过以下方式进行验证: con2>

    1.3K20发布于 2020-10-29
  • 来自专栏Java实战博客

    2 Redis 事务 & 乐观

    开启一个队列 让命令进入队列 执行事务 # 1 开启事务 multi # 2 输入命令 set k1 v1 set k2 v2 get k2 set k2 v3 get k2 # 3 执行/放弃事务 exec 或者 discard Redis 悲观 效率低,所有悲观都不建议使用 悲观:每次都会操作都会上锁,执行完毕就会释放,别人才可以获得。这样会导致效率低下,降低并发量。 Redis CAS乐观 watch操作 乐观,任何人操作都不上锁,但是真实操作时,如果这个key发现version变动了,本次修改的相关事务操作不会执行! 所有人都可以拿到,就可以提高系统吞吐量 Redis 乐观的使用场景是:电影院购票,比如C1这个作为有多人同时去抢,这张票只能被一个人抢成功。使用Redis乐观的好处是。 watch 需要Key名 # 线程1 操作:开启事务,并设置money为80 但不执行事务 multi set money 80 或者 decrby money 20 # 线程2 操作:读取money

    56520编辑于 2022-01-19
  • 来自专栏钟绍威的专栏

    原理:偏向、轻量、重量1.加锁2.撤销偏向1.加锁2.解锁3.膨胀为重量级

     java中每个对象都可作为有四种级别,按照量级从轻到重分为:无、偏向、轻量级、重量级。每个对象一开始都是无的,随着线程间争夺,越激烈,的级别越高,并且只能升级不能降级。 用2字(32位JVM中1字=32bit=4baye)存储对象头,如果是数组类型使用3字存储(还需存储数组长度)。对象头中记录了hash值、GC年龄、的状态、线程拥有者、类元数据的指针。 ? ? 2.撤销偏向  当有另一个线程来竞争的时候,就不能再使用偏向了,要膨胀为轻量级。 竞争线程尝试CAS更新对象头失败,会等待到全局安全点(此时不会执行任何代码)撤销偏向。 ? ? 三、轻量级  轻量与偏向不同的是: 轻量级每次退出同步块都需要释放,而偏向是在竞争发生时才释放 每次进入退出同步块都需要CAS更新对象头 争夺轻量级失败时,自旋尝试抢占  可以看到轻量适合在竞争情况下使用 2.解锁  用CAS操作置为无状态(偏向位为"0",标识位为"01"),若CAS操作失败则是出现了竞争,已膨胀为重量级了,此时需要释放(持有重量级锁线程的指针位为"0",标识位为"10"

    4.5K51发布于 2018-02-05
  • 来自专栏厉害了程序员

    并发模型:线程与2

    # 设置超时时间可避免死锁 time.sleep(1) lock2.acquire() # lock2.acquire(timeout=2) # 设置超时时间可避免死锁 lock1.release() lock2.release() class T2(Thread): def run(self): print ("start run T2") lock2.acquire() # lock2.acquire(timeout=2) # 设置超时时间可避免死锁 time.sleep lock1.release() def test(): t1, t2 = T1(), T2() t1.start() t2.start() t1.join () t2.join() if __name__ == "__main__": test() 交替 如果我们要在链表中插入一个节点。

    42620发布于 2020-12-22
  • 来自专栏java学习java

    redis分布式2

    index2获取了lock index2线程获取到了cpu的资源,开始执行方法 uuid=v2 set(lock,uuid); index1执行删除,此时会把index2的lock删除 index1 因为已经在方法中了 index1已经比较完成了,这个时候,开始执行 删除的index2!  定义一个:lua 脚本可以使用同一把,来实现删除! 也就是说永远存在! 重试 为了确保分布式可用,我们至少要确保的实现同时满足以下四个条件: - 互斥性。

    47940编辑于 2022-11-13
  • 来自专栏企鹅FM

    形形色色的2

    * 2. 可重入框架,相比于内置最大的区别:范围可重叠获取过程允许中断和失败支持多个条件队列可以扩展出读写、CountDownLatch、Semphore等多种灵活的形式2. 2. 双线程,有冲突类型耗时(ms)相对增幅(相对第一名)synchronized448+0%1 readlock + 1 writelock1038+132%2 writelock1137+154%3. Public2cpu缓存

    1.8K50编辑于 2022-11-22
  • 来自专栏Ryan Miao

    java线程(2)--同步和

    2、线程同步方法是通过来实现,每个对象都有切仅有一个,这个与一个特定的对象关联,线程一旦获取了对象,其他访问该对象的线程就无法再访问该对象的其他同步方法。 Thread-1释放了 Thread-2得到了 Thread-3得到了 Thread-2释放了 Thread-3释放了 Thread-4得到了 Thread-4释放了 Thread-5得到了 Thread-1 :得到了 Thread-2获取失败 Thread-0获取失败 Thread-3获取失败 Thread-1 :释放了 Thread-4 :得到了 Thread-4 :释放了 method2。    7.4.读写   读写将对一个资源(比如文件)的访问分成了2,一个读和一个写。   正因为有了读写,才使得多个线程之间的读操作不会发生冲突。   

    1.4K70发布于 2018-03-13
  • 来自专栏JavaEdge

    线程安全与优化1 线程安全2 优化

    通过计数器+-1,实现对的加锁和释放。 2 优化 2.1 自旋与自适应自旋 引入的原因是互斥同步对性能最大的影响是阻塞,挂起线程和恢复线程都需要转入内核态完成,给并发性能带来很大压力。 2.4 轻量级 2.5 偏向 大多数,在它们的生命周期中,从来不会被多于一个线程所访问。即使在极少数情况下,多个线程真的共享数据了,也不会发生竞争。 为了理解偏向的优势,我们首先需要回顾一下如何获取(监视器)。 获取的过程分为两部分。首先,你需要获得一份契约.一旦你获得了这份契约,就可以自由地拿到了。 将偏向于一个线程,意味着该线程不需要释放的契约。因此,随后获取的时候可以不那么昂贵。如果另一个线程在尝试获取,那么循环线程只需要释放契约就可以了。

    1K90发布于 2018-05-16
  • 来自专栏后端从入门到精通

    Mysql行、表 (2)—mysql进阶(六十九)

    T2和t2事务的is_waiting如果获取的是插入意向,这时候的is_Waiting就是false。 T2想对number值为3,8,15这三条记录加x型的next-key,加之前,先给表加ix,我们这里还是着重看行。 但是number为15的记录已经被T1加了s型正经record,所以T2不能获取到15的x型next-key,也就是生成的结构is_waiting为true。 因为等待状态不相同,所以这时候会生成两个结构。所以这时候属性如下: 事务T2要进行加锁,所以结构的 所在事务信息 指的就是T2. 对应事务信息:T2 索引信息:primary 行,表:spaceid 67,page number 3,n_bits为72。

    2.5K20编辑于 2022-07-29
  • 来自专栏写代码和思考

    Redis 分布式2

    分布式就是一个解决方案。 “分布式”是用来解决分布式应用中“并发冲突”的一种常用手段,实现方式一般有基于zookeeper及基于redis二种 自己写一个简单的 redis分布式 加锁时 加锁时使用 set 命令,使用 加锁执行命令 这个随机数,由客户端生成,用来标识持有的人,在删除时只能由持有的人来删除。 解锁 所以在解锁之前先判断一下是不是自己加的,是自己加的再释放,不是就不释放。 所以伪代码如下 if (random_value .equals(redisClient.get(resource_name))) { del(key) } 因为判断和解锁是2个独立的操作,不具有原子性 在尝试获取的时候,是非阻塞的,不满足在一定期限内不断尝试获取的场景。 以上两点,都可以采用 Redisson框架里的 解决

    50520编辑于 2022-09-29
  • 来自专栏分布式锁原理与源码

    分布式2.Redisson的可重入

    大纲1.Redisson可重入RedissonLock概述2.可重入源码之创建RedissonClient实例3.可重入源码之lua脚本加锁逻辑4.可重入源码之WatchDog维持加锁逻辑5.可重入源码之可重入加锁逻辑 其中KEYS[1]就是的名字如myLock,ARGV[2]为UUID + 线程ID。如果存在,说明获取的线程还在持有,并没有对进行释放。 getLockName(threadId)//ARGV[3] ); } ...}8.可重入源码之获取超时与超时自动释放逻辑(1)尝试获取超时(2)超时自动释放针对如下代码方式去获取 (1)加锁(2)WatchDog维持加锁(3)可重入(4)互斥(5)手动释放(6)宕机自动释放(7)尝试加锁超时(8)超时自动释放(1)加锁在Redis里设置两层Hash数据结构,默认的过期时间是 (2)WatchDog维持加锁如果获取的线程一直持有,那么Redis里的key就会一直保持存活。获取成功时会创建一个定时任务10秒后检查是否还被线程持有。

    36210编辑于 2025-05-09
  • 来自专栏分布式锁原理与源码

    分布式2.Redisson的可重入

    大纲1.Redisson可重入RedissonLock概述2.可重入源码之创建RedissonClient实例3.可重入源码之lua脚本加锁逻辑4.可重入源码之WatchDog维持加锁逻辑5.可重入源码之可重入加锁逻辑 里引入依赖(2)构建RedissonClient并使用Redisson(3)Redisson可重入RedissonLock简单使用(1)在pom.xml里引入依赖<dependencies> < 2.可重入源码之创建RedissonClient实例(1)初始化与Redis的连接管理器ConnectionManager(2)初始化Redis的命令执行器CommandExecutor使用Redisson.create 也就是在key为myLock的Hash值里,把field为UUID:ThreadID的value值从1累加到2,发生这种情况的时候往往就是当前线程对进行了重入。 那么就通过Redis的pttl命令,返回key为名的Hash值的剩余存活时间,因为不同线程的ARGV[2]是不一样的,ARGV[2] = UUID + 线程ID。

    44210编辑于 2025-05-09
  • 来自专栏攻城狮的那点事

    Spring Boot2+JPA之悲观和乐观实战

    通常讲到并发,解决方案无非就是前端限制重复提交,后台进行悲观或者乐观限制。 ? 在java中synchronized和ReentrantLock重入就是悲观,数据库中表、行、读写等也是悲观。 所以悲观是限制其他线程,而乐观是限制自己,虽然他的名字有,但是实际上不算上锁,通常为version版本号机制,还有CAS算法。 校验一下version版本号,发现在数据库里对应Article记录的version=2,这和我手里的版本不一样啊,说明提交的Article不是最新的,那么就不能update到数据库了,进行报错把,这样就避免了并发时数据冲突的问题 所以悲观和乐观没有绝对的好坏,必须结合具体的业务情况来决定使用哪一种方式。另外在阿里巴巴开发手册里也有提到: 如果每次访问冲突概率小于 20%,推荐使用乐观,否则使用悲观

    4K50发布于 2020-01-14
  • 来自专栏JavaEdge

    MySQL的1 MySql的三种2模式3 MyISAM的并发4 InnoDB问题5 关于死锁6 总结7 索引与

    ' //table_locks_waited 的值越高,则说明存在严重的表级的争用情况 2模式 是否兼容 请求none 请求读 请求写 当前处于读 是 是 否 当前处于写 是 否 否 ,必须同时取得所有涉及的表的,并且MySQL支持升级 即在执行lock tables后,只能访问显式加锁的这些表,不能访问未加锁的表 加的是读,就只能查询,不能更新 session1 session2 unlock tables 等待 获得,更新成功 在自动加锁的情况下也如此,MySQL会一次获得SQL语句所需要的全部 所以MyISAM的表不会死锁 session1 session2 获得表 where id=1 获得,更新成功 4.5.2 Innodb排他 session_1 session_2 set autocommit=0,select * from actor where 此时,只有一个线程能插入成功,另一个线程会出现等待,当第1个线程提交后,第个线程会因主键重出错,但虽然这个线程出错了,却会获得一个排他!这时如果有第3个线程又来申请排他,也会出现死锁。

    2.3K60发布于 2018-05-16
  • 来自专栏java小记

    java多线程学习(2)-的使用

    简介 上篇已经对的属性做了一个简单的介绍,此篇主要针对于不同的使用,分析优缺点,方便以后使用的时候能选择合适的。 methodTwo:thread-2 will leave:thread-2 从控制台输出可以看出,methodOne进入了methodTwo,说明synchronized是可重入; 然后thread1 (true); ReentrantReadWriteLock 此能获取两种类型的,读和写,读是共享,写是排他,读读共享,读写互斥,此也可以构造公平与非公平 我们将上面的代码改造使用ReentrantReadWriteLock public SimpleReentrantReadWriteLock(int var1,String var2) { this.var1 = var1; this.var2 read(); break; case 2: write(var2); break

    69330发布于 2018-07-14
  • 来自专栏全栈程序员必看

    mysql表和解锁语句_db2查看是否

    当concurrent_insert设置为2时,无论MyISAM表中有没有空洞,都允许在表尾并发插入记录。 当前线程执行另一个 LOCK TABLES 时, 或当与服务器的连接被关闭时,所有由当前线程锁定的表被隐含地解锁 加锁语法 LOCK TABLES t1 WRITE, t2 READ, ...; 按我经验来说基本上都是竞争太强烈导致的,比如定时器1秒执行一次,而定时器里的的代码逻辑比较复杂执行时间>1秒那么这样长久下去早晚出事 如果不上面情况那么你就需要按照下面这些情况慢慢的排查了 1)sql未使用索引,更新或删除单表中的数据 2) DDL(修改表结构…)操作或加索引操作,这也会造成表 重点: 第2条和第4条发生几率很高 死锁的预防措施 既然知道了表以后,我们有一些事后的补救措施,那我们是不是在刚开始设计的时候就可以尽可能规避这些坑呢 答案是有的,如下所示 1)对于大表的操作,查询条件一定要保证命中索引,如果能命中唯一索引就更好了 2)我们在程序开发的时候,尽可能将大事务拆分为小事务,减少表或回滚,比如:抽离部分业务逻辑异步发送消息队列处理

    4K40编辑于 2022-09-25
  • 来自专栏软件工程

    独占(写)共享(读)互斥

    独占:指该一次只能被一个线程所持有。对ReentrantLock和Synchronized而言都是独占 共享:指该可被多个线程所持有。 对ReentrantReadWriteLock其读是共享,其写是独占。 读的共享可保证并发读是非常高效的,读写,写读,写写的过程是互斥的。 使用方法 声明一个读写 如果需要独占则加从可重入读写里得到写demo 如果需要共享则加从可重入读写里得到读demo ReentrantReadWriteLock实现原理简单分析 清单2:读写状态获取 static final int SHARED_SHIFT = 16; static final int SHARED_UNIT = (1 << SHARED_SHIFT ,低16位表示写个数 一个线程获取到了写,并且重入了两次,低16位是3,线程又获取了读,并且重入了一次,高16位就是2的写的获取主要调用AQS的相关Acquire方法,其释放主要用了相关Release

    1.7K30编辑于 2022-05-13
  • 来自专栏yukong的小专栏

    【java并发编程实战2】无编程CAS与atomic包1、无编程CAS2、 atomic族类

    基于这样的原理,CAS操作即使没有,同样知道其他线程对共享资源操作影响,并执行相应的处理措施。 同时从这点也可以看出,由于无操作中没有的存在,因此不可能出现死锁的情况,也就是说无操作天生免疫死锁。 do { var5 = this.getIntVolatile(var1, var2); } while(! this.compareAndSwapInt(var1, var2, var5, var5 + var4)); return var5; } 上面就是getAndAddInt 方法的实现,具体流程如下, 1、首先根据当前的传过来的对象指针,获取期望的值 var5, 2、然后while判断调用compareAndSwapInt方法 ,这是一个native本地方法,它有四个参数

    81430发布于 2018-09-03
领券