数据库死锁

并发编程中一些问题

假如想象 提交于 2020-02-03 22:00:02
多线程就一定好吗?快吗?? 并发编程的目的就是为了能提高程序的执行效率提高程序运行速度,但是并发编程并不总是能提高程序运行速度的,而且并发编程可能会遇到很多问题,比如:内存泄漏、上下文切换、死锁还有受限于硬件和软件的资源闲置问题。 多线程就是几乎同时执行多个线程(一个处理器在某一个时间点上永远都只能是一个线程!即使这个处理器是多核的,除非有多个处理器才能实现多个线程同时运行)。CPU通过给每个线程分配CPU时间片来实现伪同时运行,因为CPU时间片一般很短很短,所以给人一种同时运行的感觉。 上下文切换 当前任务在执行完CPU时间片切换到另一个任务之前会先保存自己的状态,以便下次再切换会这个任务时,可以再加载这个任务的状态。 任务从保存到再加载的过程就是一次上下文切换。 上下文切换通常是计算密集型的。也就是说,它需要相当可观的处理器时间,在每秒几十上百次的切换中,每次切换都需要纳秒量级的时间。所以, 上下文切换对系统来说意味着消耗大量的 CPU 时间 ,事实上,可能是操作系统中时间消耗最大的操作。 Linux相比与其他操作系统(包括其他类 Unix 系统)有很多的优点,其中有一项就是,其上下文切换和模式切换的时间消耗非常少。 减少上下文切换 上下文切换又分为2种: 让步式上下文切换 和 抢占式上下文切换 。前者是指执行线程主动释放CPU,与锁竞争严重程度成正比,可通过 减少锁竞争

多线程面试60题超详解

久未见 提交于 2020-01-31 09:24:54
多线程面试60题 1.多线程有什么用? 2.线程和进程的区别是什么? 3.Java 实现线程有哪几种方式? 4.启动线程方法 start()和 run()有什么区别? 5.怎么终止一个线程? 6.一个线程的生命周期有哪几种状态?它们之间如何流转的? 7.线程中的 wait()和 sleep()方法有什么区别? 8.多线程同步有哪几种方法? 9.什么是死锁?如何避免死锁? 10.多线程之间如何进行通信? 11、线程怎样拿到返回结果? 12、violatile 关键字的作用? 13、新建 T1、T2、T3 三个线程,如何保证它们按顺序执行? 14、怎么控制同一时间只有 3 个线程运行? 15、为什么要使用线程池? 16、常用的几种线程池并讲讲其中的工作原理。 什么是线程池? 线程池的好处 如何提交线程 submit 和 execute 分别有什么区别呢? 如何关闭线程池es.shutdown()? 17、线程池启动线程 submit()和 execute()方法有什么不同? 18、CyclicBarrier 和 CountDownLatch 的区别? 19、什么是活锁、饥饿、无锁、死锁? 20、什么是原子性、可见性、有序性? 21、什么是守护线程?有什么用? 什么是守护线程? 22、一个线程运行时发生异常会怎样? 23、线程 yield()方法有什么用? 24、什么是重入锁? 25

select for update引发死锁分析

一世执手 提交于 2020-01-26 20:22:48
本文针对MySQL InnoDB中在Repeatable Read的隔离级别下使用select for update可能引发的死锁问题进行分析。 1. 业务案例 业务中需要对各种类型的实体进行编号,例如对于x类实体的编号可能是x201712120001,x201712120002,x201712120003类似于这样。可以观察到这类编号有两个部分组成:x+日期作为前缀,以及流水号(这里是四位的流水号)。 如果用数据库表实现一个能够分配流水号的需求,无外乎就可以建立一个类似于下面的表: CREATE TABLE number ( prefix VARCHAR(20) NOT NULL DEFAULT '' COMMENT '前缀码', value BIGINT NOT NULL DEFAULT 0 COMMENT '流水号', UNIQUE KEY uk_prefix(prefix) ); 那么在业务层,根据业务规则得到编号的前缀比如x20171212,接下去就可以在代码中起事务,用select for update进行如下的控制。 @Transactional long acquire(String prefix) { SerialNumber current = dao.selectAndLock(prefix); if (current == null) { dao

数据库死锁解决办法

别说谁变了你拦得住时间么 提交于 2020-01-26 13:50:33
1.之前遇到过一个场景:有一个用户登录一直失败,但是其他用户却可以正常登录,后来测试借口发现在登录时更新这个用户的登录时间时,一直没有反应然后超时了。因为innordb是行级锁的所以就想到了是这条用户的信息被锁住了。 2.解决方案: 执行语句:SELECT * FROM information_schema.INNODB_TRX\G ; *************************** 1. row *************************** trx_id: 189324 trx_state: RUNNING trx_started: 2013-04-18 17:48:14 trx_requested_lock_id: NULL trx_wait_started: NULL trx_weight: 3 trx_mysql_thread_id: 16 trx_query: NULL trx_operation_state: NULL trx_tables_in_use: 0 trx_tables_locked: 0 trx_lock_structs: 2 trx_lock_memory_bytes: 376 trx_rows_locked: 3 trx_rows_modified: 1 trx_concurrency_tickets: 0 trx_isolation

oracle锁与死锁概念,阻塞产生的原因以及解决方案

情到浓时终转凉″ 提交于 2020-01-26 09:20:00
锁是一种机制,一直存在;死锁是一种错误,尽量避免。​ 首先,要理解锁和死锁的概念:​ 1、锁: 定义:简单的说,锁是数据库为了保证数据的一致性而存在的一种机制,其他数据库一样有,只不过实现机制上可能大相径庭。​ 那么,锁的种类有哪些?锁的种类有很多,根据保护的对象不同,Oracle数据库锁可以分为以下几大类:DML锁(data locks,数据锁),用于保护数据的完整性;DDL锁(dictionary locks,字典锁),用于保护数据库对象的结构,如表、索引等的结构定义;内部锁和闩(internal locks and latches),保护 数据库的内部结构。​ 在实际项目中遇到的最多的是DML锁,也可进一步说是行级锁。这些行级锁在程序并发访问的时候会造成程序很慢,或者直接访问不了的情况—这种现象称为阻塞。那么,产生阻塞的原因是什么呢?定义:当一个会话保持另一个会话正在请求的资源锁定时,就会发生阻塞。被阻塞的会话将一直挂起,直到持有锁的会话放弃锁定的资源为止。四个常见的DML语句会产生阻塞: 1)INSERT 2)​UPDATE 3)DELETE ​4)SELECT…FOR UPDATE​ 2、死锁: 定义:当两个用户同时希望持有对方的资源时就会发生死锁。即当两个用户互相等待对方释放资源时,oracle认定产生了死锁,在这种情况下,将以牺牲一个用户为代价,另一个用户继续执行

数据库中锁有哪些,遇到死锁怎么解决

故事扮演 提交于 2020-01-19 11:34:54
锁的概念: 首先我们先了解下什么是数据库锁, 锁是事务对某个数据库中的资源(如表和记 录)存取前,先向系统提出请求,封锁该资源, 事务获得锁后,即取得对数据的控制权,在事务释放它的锁之前,其他事务不能更新此数据。当事务撤消后,释放被 锁定的资源。 数据库锁的分类: 共享锁:又叫S锁或者读锁,加了共享锁的数据对象可以被其他事务读取,但不能修改, 通常是该数据对象被读取完毕,锁立即被释放 排他锁:又叫X锁或者写锁,当数据对象被加上排它锁时,一个事务必须得到锁才能对该数据对象进行访问,一直到事务结束锁才被释放。 在此之间其他的事 务不能对它读取和修改。 死锁: 死锁是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。 这些永远在互相等待的进程称为死锁进程 产生死锁的必要条件: 1、互斥使用,即当资源被一个线程使用(占有)时,别的线程不能使用 2、不可抢占,资源请求者不能强制从资源占有者手中夺取资源,资源只能由资源占有者主动释放。 3、请求和保持,即当资源请求者在请求其他的资源的同时保持对原有资源的占有。 4、循环等待,即存在一个等待队列:P1占有P2的资源,P2占有P3的资源,P3占有P1的资源。这样就形成了一个等待环路。 死锁产生的原因: 1) 系统资源的竞争 通常系统中拥有的不可剥夺资源

一次活动引发的血案

泪湿孤枕 提交于 2020-01-19 03:41:31
本文来自 网易云社区 作者: 方金德 “咚咚”,接连收到好几个报警短信,显示线上集群的几个tomcat应用的接连端口异常。不好,线上可能出状况了,访问网站,果然已经显示为维护中了。赶紧登陆到服务器,但服务器的cpu,load,内存,io等基本指标都还是挺正常的,应用日志端也没有明显异常信息,不过nginx的访问日志的确显示后端服务器都已基本为504请求超时了。不管那么多了,距离上次发布已经有几个小时了,应该不是新版本bug直接导致的问题,先尝试不回滚重启吧。于是火速重启了集群中一个节点,很快线上应用访问正常了。然后把另外两个节点的jvm的stack和memory信息导出来后,也重启后加回到线上。 线上是正常了,但我们其实并没有找到问题的原因。没有找到问题的诱因,也就意味着这个问题可能还会再发生。和相关的同事们再一起排查了一遍线上应用日志和tomcat容器日志,也没有发现什么可挖掘的异常点。再跑到网易的监控平台看历史的监控数据,系统层面的cpu、load、 中断、 memory、 swap、 ioutil、网络流量等都没有特别的异常;jvm层面的gc、thread数也都没有什么明显异常。gc没有问题,直接放弃了memory dump信息的查看。再简单地看了下jstack信息,好像也没有什么异常,统计了下线程数,跟线上的线程数也差不多,猜测应该也不是属于并发超限吧。。。

死锁产生的原因和解锁的方法

China☆狼群 提交于 2020-01-18 04:00:55
一.产生死锁的四个必要条件: (1) 互斥条件:一个资源每次只能被一个进程使用。 (2) 请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。 (3) 不剥夺条件:进程已获得的资源,在末使用完之前,不能强行剥夺。 (4) 循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。 二 锁的分类 锁的类别有两种分法: 1. 从数据库系统的角度来看:分为独占锁(即排它锁),共享锁和更新锁 MS-SQL Server 使用以下资源锁模式。 锁模式描述:   共享 (S) :读锁,用于不更改或不更新数据的操作(只读操作),如 SELECT 语句。   更新 (U) :( 介于共享和排它锁之间 ),可以让其他程序在不加锁的条件下读,但本程序可以随时更改。   读取表时使用更新锁,而不使用共享锁,并将锁一直保留到语句或事务的结束。UPDLOCK 的优点是允许您读取数据(不阻塞其它事务)并在以后更新数据,同时确保自从上次读取数据后数据没有被更改。当我们用UPDLOCK来读取记录时可以对取到的记录加上更新锁,从而加上锁的记录在其它的线程中是不能更改的只能等本线程的事务结束后才能更改,我如下示例: BEGIN TRANSACTION --开始一个事务 SELECT Qty FROM myTable WITH (UPDLOCK) WHERE Id in (1,2,3) UPDATE

常见的表死锁情况及解决方法

可紊 提交于 2020-01-18 03:58:03
1、死锁的第一种情况 一个用户A 访问表A(锁住了表A),然后又访问表B;另一个用户B 访问表B(锁住了表B),然后企图访问表A;这时用户A由于用户B已经锁住表B,它必须等待用户B释放表B才能继续,同样用户B要等用户A释放表A才能继续,这就死锁就产生了。 解决方法 这种死锁比较常见,是由于程序的BUG产生的,除了调整的程序的逻辑没有其它的办法。仔细分析程序的逻辑,对于数据库的多表操作时,尽量按照相同的顺序进行处理,尽量避免同时锁定两个资源,如操作A和B两张表时,总是按先A后B的顺序处理, 必须同时锁定两个资源时,要保证在任何时刻都应该按照相同的顺序来锁定资源。 2、死锁的第二种情况 用户A查询一条纪录,然后修改该条纪录;这时用户B修改该条纪录,这时用户A的事务里锁的性质由查询的共享锁企图上升到独占锁,而用户B里的独占锁由于A有共享锁存在所以必须等A释放掉共享锁,而A由于B的独占锁而无法上升的独占锁也就不可能释放共享锁,于是出现了死锁。这种死锁比较隐蔽,但在稍大点的项目中经常发生。如在某项目中,页面上的按钮点击后,没有使按钮立刻失效,使得用户会多次快速点击同一按钮,这样同一段代码对数据库同一条记录进行多次操作,很容易就出现这种死锁的情况。 解决方法 1、对于按钮等控件,点击后使其立刻失效,不让用户重复点击,避免对同时对同一条记录操作。 2、使用乐观锁进行控制。乐观锁大多是基于数据版本

MySQL死锁

冷暖自知 提交于 2020-01-18 03:56:52
Reference: https://time.geekbang.org/column/article/117247 死锁产生 行锁的具体实现算法有三种:record lock、gap lock以及next-key lock。 record lock是专门对索引项加锁; gap lock是对索引项之间的间隙加锁; next-key lock则是前面两种的组合,对索引项及其之间的间隙加锁。 只在可重复读或以上隔离级别下的特定操作才会取得gap lock或next-key lock,在Select、Update和Delete时,除了基于唯一索引的查询之外,其它索引查询时都会获取gap lock或next-key lock,即锁住其扫描的范围。主键索引也属于唯一索引,所以主键索引是不会使用gap lock或next-key lock。 在MySQL中,gap lock默认是开启的,即innodb_locks_unsafe_for_binlog参数值是disable的,且MySQL中默认的是RR事务隔离级别。 当执行以下查询SQL时,由于order_no列为非唯一索引,此时又是RR事务隔离级别,所以SELECT的加锁类型为gap lock,这里的gap范围是(4,+∞)。 1 SELECT id FROM demo.order_record where order_no = 4 for