共 6 页: 上一页 1 2 3 4 5 6 下一页
摘要:InnoDB是一个支持行锁的存储引擎,它有三种行锁的算法: Record Lock:行锁,单个行记录上的锁。 Gap Lock:间隙锁,锁定一个范围,但不包括记录本身。GAP锁的目的,是为了防止幻读、防止间隙内有新数据插入、防止已存在的数据更新为间隙内的数据。 Next-Key Lock:1+2,锁定一个范围,并且锁定记录本身。对于行的查询,都是采用该方法,主要目的是解决幻读的问题。InnoDB... 阅读全文
posted @ 2019-02-09 23:01 robin·张 阅读 (35) 评论 (0) 编辑
摘要:什么是MVVC? MVVC (Multi-Version Concurrency Control) (注:与MVCC相对的,是基于锁的并发控制,Lock-Based Concurrency Control)是一种基于多版本的并发控制协议,只有在InnoDB引擎下存在。MVCC是为了实现事务的隔离性,通过版本号,避免同一数据在不同事务间的竞争,你可以把它当成基于多版本号的一种乐观锁。当然,这种乐观锁... 阅读全文
posted @ 2019-02-09 01:02 robin·张 阅读 (25) 评论 (0) 编辑
摘要:ANSI/ISO SQL定义的标准隔离级别有四种,从高到底依次为:可序列化(Serializable)、可重复读(Repeatable reads)、提交读(Read committed)、未提交读(Read uncommitted)。 下面将依次介绍这四种事务隔离级别的概念、用法以及解决了哪些问题(读现象) 未提交读(Read uncommitted) 未提交读(READ UNCOMMITTED... 阅读全文
posted @ 2019-02-07 23:58 robin·张 阅读 (45) 评论 (0) 编辑
摘要:为什么需要隔离 当多个线程都开启事务操作数据库中的数据时,数据库系统要能进行隔离操作,以保证各个线程获取数据的准确性,在介绍数据库提供的各种隔离级别之前,我们先看看如果不考虑事务的隔离性,会发生的几种问题: 脏读 脏读是指在一个事务处理过程里读取了另一个未提交的事务中的数据。 当一个事务正在多次修改某个数据,而在这个事务中这多次的修改都还未提交,这时一个并发的事务来访问该数据,就会造成两个事务得到... 阅读全文
posted @ 2019-02-07 23:42 robin·张 阅读 (12) 评论 (0) 编辑
摘要:数据库事务(Database Transaction) ,是指作为单个逻辑工作单元执行的一系列操作,要么完全地执行,要么完全地不执行。事务处理可以确保除非事务性单元内的所有操作都成功完成,否则不会永久更新面向数据的资源。通过将一组相关操作组合为一个要么全部成功要么全部失败的单元,可以简化错误恢复并使应用程序更加可靠。一个逻辑工作单元要成为事务,必须满足所谓的ACID(原子性、一致性、隔离性和持久性... 阅读全文
posted @ 2019-02-07 23:32 robin·张 阅读 (24) 评论 (0) 编辑
摘要:死锁产生 死锁是指两个或多个事务在同一资源上相互占用,并请求锁定对方占用的资源,从而导致恶性循环。 当事务试图以不同的顺序锁定资源时,就可能产生死锁。多个事务同时锁定同一个资源时也可能会产生死锁。 锁的行为和顺序和存储引擎相关。以同样的顺序执行语句,有些存储引擎会产生死锁有些不会——死锁有双重原因:真正的数据冲突;存储引擎的实现方式。 检测死锁 数据库系统实现了各种死锁检测和死锁超时的机制。Inn... 阅读全文
posted @ 2019-02-07 00:10 robin·张 阅读 (1028) 评论 (0) 编辑
摘要:锁粒度 MySQL 不同的存储引擎支持不同的锁机制,所有的存储引擎都以自己的方式显现了锁机制,服务器层完全不了解存储引擎中的锁实现: InnoDB 存储引擎既支持行级锁(row-level locking),也支持表级锁,但默认情况下是采用行级锁。 MyISAM 和 MEMORY 存储引擎采用的是表级锁(table-level locking) BDB 存储引擎采用的是页面锁(page-le... 阅读全文
posted @ 2019-02-07 00:04 robin·张 阅读 (38) 评论 (0) 编辑
摘要:乐观锁 乐观锁是逻辑概念上的锁,不是数据库自带的,需要我们自己去实现。乐观锁是指操作数据库时(更新操作),想法很乐观,认为这次的操作不会导致冲突,在操作数据时,并不进行任何其他的特殊处理(也就是不加锁),而在进行更新后,再去判断是否有冲突了。 通常实现是这样的:在表中的数据进行操作时(更新),先给数据表加一个版本(version)字段,每操作一次,将那条记录的版本号加1。也就是先查询出那条记录,获... 阅读全文
posted @ 2019-02-06 22:54 robin·张 阅读 (31) 评论 (0) 编辑
摘要:索引选择性 索引选择性是索引基数(cardinality)与表中数据行数(n_row_in_table)的比值,即 索引选择性=索引基数/数据行 其中cardinality是索引中不重复记录的预估值。 不是所有的查询条件出现的列都需要添加索引。对于什么时候添加B+树索引。一般的经验是,在访问表中很少一部分时使用B+树索引才有意义。对于性别字段、地区字段、类型字段,他们可取值范围很小,称为低选择性... 阅读全文
posted @ 2019-02-06 00:18 robin·张 阅读 (32) 评论 (0) 编辑
摘要:执行计划,简单的来说,是SQL在数据库中执行时的表现情况,通常用于SQL性能分析,优化等场景。在MySQL中使用 explain 关键字来查看。如下所示: explain select * from table where table.id = 1 运行上面的sql语句后你会看到,下面的表头信息: table | type | possible_keys | key | key_len | re... 阅读全文
posted @ 2019-02-05 22:47 robin·张 阅读 (29) 评论 (0) 编辑
摘要:通过实例理解单列索引、多列索引以及最左前缀原则 实例:现在我们想查出满足以下条件的用户id: SELECT `uid` FROM people WHERE lname`='Liu' AND `fname`='Zhiqun' AND `age`=26 因为我们不想扫描整表,故考虑用索引。 单列索引: ALTER TABLE people ADD INDEX lname (lname);将ln... 阅读全文
posted @ 2019-02-04 22:32 robin·张 阅读 (27) 评论 (0) 编辑
摘要:WHERE字句的查询条件里有不等于号(WHERE column!=…),MYSQL将无法使用索引 类似地,如果WHERE字句的查询条件里使用了函数(如:WHERE DAY(column)=…),MYSQL将无法使用索引 在JOIN操作中(需要从多个数据表提取数据时),MYSQL只有在主键和外键的数据类型相同时才能使用索引,否则即使建立了索引也不会使用 如果WHERE子句的查询条件里使用了比较操作... 阅读全文
posted @ 2019-02-04 22:26 robin·张 阅读 (127) 评论 (0) 编辑
摘要:mysql的索引分为单列索引(主键索引,唯索引,普通索引)和组合索引. 单列索引:一个索引只包含一个列,一个表可以有多个单列索引. 组合索引:一个组合索引包含两个或两个以上的列, 本文案例使用的表: CREATE TABLE `award` ( `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '用户id', `aty_id` varchar... 阅读全文
posted @ 2019-02-04 22:22 robin·张 阅读 (31) 评论 (0) 编辑
摘要:一、定义 索引定义:索引(Index)是帮助MySQL高效获取数据的数据结构。本质:索引是数据结构。 二、B-Tree m阶B-Tree满足以下条件: 每个节点至多可以拥有m棵子树。 根节点,只有至少有2个节点(要么极端情况,就是一棵树就一个根节点,单细胞生物,即是根,也是叶,也是树)。 非根非叶的节点至少有的Ceil(m/2)个子树(Ceil表示向上取整,如5阶B树,每个节点至少有3个子树,也... 阅读全文
posted @ 2019-02-03 23:56 robin·张 阅读 (78) 评论 (0) 编辑
摘要:主索引 将主文件分块,每一块对应一个索引项。每个存储快的第一条记录,又称为锚记录。 主索引是按照索引字段值进行排序的一个有序文件,通常建立在有序文件的基于主码的排序字段上。 主索引是稀疏索引。 辅助索引 定义:定义在主文件的任意一个或者多个非排序字段上的辅助存储结构。 辅助索引通常对字段(该字段非排序)的每一个不同值有一个索引项。 字段值不唯一,引入中间桶保存指针列表。 辅助索引是稠密索引。 二... 阅读全文
posted @ 2019-02-03 23:01 robin·张 阅读 (49) 评论 (0) 编辑
摘要:聚集索引 索引中键值的逻辑顺序决定了表中相应行的物理顺序(索引中的数据物理存放地址和索引的顺序是一致的),可以这么理解:只要是索引是连续的,那么数据在存储介质上的存储位置也是连续的。 聚集索引就像我们根据拼音的顺序查字典一样,可以大大的提高效率。在经常搜索一定范围的值时,通过索引找到第一条数据,根据物理地址连续存储的特点,然后检索相邻的数据,直到到达条件截至项。 InnoDB引擎的数据文件本身就是... 阅读全文
posted @ 2019-02-03 22:26 robin·张 阅读 (47) 评论 (0) 编辑
摘要:客户端方案 禁掉提交按钮。 表单提交后使用Javascript使提交按钮disable。这种方法防止心急的用户多次点击按钮。但有个问题,如果客户端把Javascript给禁止掉,这种方法就无效了。 使用Post/Redirect/Get模式 在提交后执行页面重定向,这就是所谓的Post-Redirect-Get (PRG)模式。简言之,当用户提交了表单后,你去执行一个客户端的重定向,转到提交成功信... 阅读全文
posted @ 2019-02-02 23:03 robin·张 阅读 (123) 评论 (0) 编辑
摘要:主要是因为i++这个操作不是原子性的,它会编译成 i = i +1; 其实是做了3个步骤,一个是读取,修改,写入 。所以会出现多线程访问冲突问题。 可以结合Java内存模型来进行说明。 阅读全文
posted @ 2019-02-01 23:44 robin·张 阅读 (43) 评论 (0) 编辑
摘要:先看下三次握手四次挥手的状态变化: 通常会遇到下面两种情况: 服务器保持了大量TIME_WAIT状态 服务器保持了大量CLOSE_WAIT状态 因为linux分配给一个用户的文件句柄是有限的,而TIME_WAIT和CLOSE_WAIT两种状态如果一直被保持,那么意味着对应数目的通道就一直被占着,而且是“占着茅坑不使劲”,一旦达到句柄数上限,新的请求就无法被处理了,接着就是大量Too Many ... 阅读全文
posted @ 2019-02-01 23:39 robin·张 阅读 (24) 评论 (0) 编辑
摘要:TCP头部 源端口和目的端口在TCP层确定双方进程,序列号表示的是报文段数据中的第一个字节号,ACK表示确认号,该确认号的发送方期待接收的下一个序列号,即最后被成功接收的数据字节序列号加1,这个字段只有在ACK位被启用的时候才有效。 当新建一个连接时,从客户端发送到服务端的第一个报文段的SYN位被启用,这称为SYN报文段,这时序列号字段包含了在本次连接的这个方向上要使用的第一个序列号,即初始序列... 阅读全文
posted @ 2019-01-31 23:02 robin·张 阅读 (45) 评论 (0) 编辑
摘要:get和post的区别可以从三个层面来说:浏览器/服务器层面、HTTP协议层面、语义层面。 浏览器/服务器层面 二者在浏览器层面有着多方面的不同: GET把参数写在URL中,POST通过body来传参。 GET后退按钮/刷新无害,POST数据会被重新提交(浏览器应该告知用户数据会被重新提交)。 GET书签可收藏,POST为书签不可收藏。 GET能被缓存,POST不能缓存 。 GET编码类型app... 阅读全文
posted @ 2019-01-30 23:25 robin·张 阅读 (20) 评论 (0) 编辑
摘要:session其实分为服务器端Session和客户端Session。 当用户首次与Web服务器建立连接的时候,服务器会给用户分发一个sessionid作为标识。用户每次提交页面,浏览器都会把这个sessionid包含在 HTTP头中提交给Web服务器,这样Web服务器就能区分当前请求页面的是哪一个客户端。这个sessionid就是保存在客户端的,属于客户端Session。 tomcat生成的ses... 阅读全文
posted @ 2019-01-29 23:41 robin·张 阅读 (22) 评论 (0) 编辑
摘要:二者的区别简单说就是Cookie通过在客户端记录信息确定用户身份,Session通过在服务器端记录信息确定用户身份。 关于Cookie Cookie实际上是一小段的文本信息。客户端请求服务器,如果服务器需要记录该用户状态,就使用response向客户端浏览器颁发一个Cookie。客户端会把Cookie保存起来。 当浏览器再请求该网站时,浏览器把请求的网址连同该Cookie一同提交给服务器。服务器检... 阅读全文
posted @ 2019-01-29 23:08 robin·张 阅读 (14) 评论 (0) 编辑
摘要:先说结论:servlet不是线程安全的。 servlet运行过程 Servlet程序是由WEB服务器调用,web服务器收到客户端的Servlet访问请求后: ①Web服务器首先检查是否已经装载并创建了该Servlet的实例对象。如果是,则直接执行第④步,否则,执行第②步。 ②装载并创建该Servlet的一个实例对象。 ③调用Servlet实例对象的init()方法。 ④创建一个用于封装HTTP请... 阅读全文
posted @ 2019-01-28 23:17 robin·张 阅读 (11) 评论 (0) 编辑
摘要:AQS即队列同步器AbstractQueuedSynchronizer(以下简称同步器),是用来构建锁或者其他同步组件的基础框架。 AQS使用了一个int成员变量表示同步状态。 AQS通过内置的FIFO双向队列来完成获取锁线程的排队工作 同步器包含两个节点类型的应用,一个指向头节点,一个指向尾节点,未获取到锁的线程会创建节点线程安全(compareAndSetTail)的加入队列尾部。同步队列遵... 阅读全文
posted @ 2019-01-27 22:33 robin·张 阅读 (30) 评论 (0) 编辑
摘要:无锁竞争的情况下为了减少锁竞争的资源开销,引入偏向锁。 阅读全文
posted @ 2019-01-27 22:19 robin·张 阅读 (14) 评论 (0) 编辑
摘要:轻量级锁所适应的场景是线程交替执行同步块的情况。 阅读全文
posted @ 2019-01-27 22:13 robin·张 阅读 (19) 评论 (0) 编辑
摘要:Synchronized是通过对象内部的一个叫做监视器锁(monitor)来实现的。但是监视器锁本质又是依赖于底层的操作系统的Mutex Lock来实现的。而操作系统实现线程之间的切换这就需要从用户态转换到核心态,这个成本非常高,状态之间的转换需要相对比较长的时间,这就是为什么Synchronized效率低的原因。因此,这种依赖于操作系统Mutex Lock所实现的锁我们称之为“重量级锁”。 JD... 阅读全文
posted @ 2019-01-27 22:10 robin·张 阅读 (13) 评论 (0) 编辑
摘要:CAS,在Java并发应用中通常指CompareAndSwap或CompareAndSet,即比较并交换。 CAS是一个原子操作,它比较一个内存位置的值并且只有相等时修改这个内存位置的值为新的值,保证了新的值总是基于最新的信息计算的,如果有其他线程在这期间修改了这个值则CAS失败。CAS返回是否成功或者内存位置原来的值用于判断是否CAS成功。 JVM中的CAS操作是利用了处理器提供的CMPXCHG... 阅读全文
posted @ 2019-01-27 22:06 robin·张 阅读 (21) 评论 (0) 编辑
摘要:如果一系列的连续操作都对同一个对象反复加锁和解锁,甚至加锁操作是出现在循环体中的,那即使没有线程竞争,频繁地进行互斥同步操作也会导致不必要的性能损耗。 如果虚拟机探测到有这样一串零碎的操作都对同一个对象加锁,将会把加锁同步的范围扩展(膨胀)到整个操作序列的外部(由多次加锁编程只加锁一次)。 一种需要锁粗化的极端的情况是: for(int i=0;i<size;i++){ synchroni... 阅读全文
posted @ 2019-01-27 22:04 robin·张 阅读 (25) 评论 (0) 编辑
摘要:锁消除是指虚拟机即时编译器在运行时,对一些代码上要求同步,但是被检测到不可能存在共享数据竞争的锁进行削除。锁削除的主要判定依据来源于逃逸分析的数据支持,如果判断到一段代码中,在堆上的所有数据都不会逃逸出去被其他线程访问到,那就可以把它们当作栈上数据对待,认为它们是线程私有的,同步加锁自然就无须进行。 比如StringBuffer的append方法用了synchronized关键词,它是线程安全的... 阅读全文
posted @ 2019-01-27 22:02 robin·张 阅读 (14) 评论 (0) 编辑
摘要:JavaSE1.6为了减少获得锁和释放锁带来的性能消耗,引入了“偏向锁”和“轻量级锁”。 在JavaSE1.6中,锁一共有4种状态,级别从低到高依次是:无锁状态、偏向锁状态、轻量级锁状态和重量级锁状态,这几个状态会随着竞争情况逐渐升级。 锁可以升级但不能降级,意味着偏向锁升级成轻量级锁后不能降级成偏向锁。这种锁升级却不能降级的策略,目的是为了提高获得锁和释放锁的效率。 阅读全文
posted @ 2019-01-27 21:44 robin·张 阅读 (13) 评论 (0) 编辑
摘要:synchronized是基于Monitor来实现同步的。 Monitor 的工作机理: 线程进入同步方法中。 为了继续执行临界区代码,线程必须获取 Monitor 锁。如果获取锁成功,将成为该监视者对象的拥有者。任一时刻内,监视者对象只属于一个活动线程(The Owner) 拥有监视者对象的线程可以调用 wait() 进入等待集合(Wait Set),同时释放监视锁,进入等待状态。 其他线程调... 阅读全文
posted @ 2019-01-27 21:42 robin·张 阅读 (26) 评论 (0) 编辑
摘要:ThreadLocal ThreadLocal是一个本地线程副本变量工具类。主要用于将私有线程和该线程存放的副本对象做一个映射,各个线程之间的变量互不干扰,在高并发场景下,可以实现无状态的调用,特别适用于各个线程依赖不通的变量值完成操作的场景。 下图为ThreadLocal的内部结构图: 从上图可知ThreadLocal的结构 每个Thread线程内部都有一个Map。 Map里面存储线程本地对... 阅读全文
posted @ 2019-01-26 23:11 robin·张 阅读 (21) 评论 (0) 编辑
摘要:Java线程池ThreadPoolExecutor的构造器: public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, ... 阅读全文
posted @ 2019-01-25 23:44 robin·张 阅读 (25) 评论 (0) 编辑
摘要:Java的线程池都是通过ThreadPoolExecutor来构建。 public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, ... 阅读全文
posted @ 2019-01-25 23:24 robin·张 阅读 (203) 评论 (0) 编辑
摘要:volatile关键字有两个特性: volatile变量对所有线程的可见性,指当一条线程修改了这个变量的值,新值对于其他线程来说是可以立即得知的。 volatile变量可以禁止指令重排序优化。 因为JVM要求线程每次使用工作内存中的volatile变量时,都必须从主内存中刷新获取最新的值;执行线程每次修改工作内存中的volatile变量后也必须立刻将之同步回主内存,这样一个线程修改了volati... 阅读全文
posted @ 2019-01-21 23:45 robin·张 阅读 (19) 评论 (0) 编辑
摘要:Java内存模型规定了所有的变量都存储在主内存(MainMemory)中;线程的工作内存中保存了被该线程使用到的变量的主内存副本拷贝;线程对变量的所有操作(读取、赋值等)都必须在工作内存中进行,而不能直接读写主内存中的变量。 不同的线程之间也无法直接访问对方工作内存中的变量,线程间变量值的传递均需要通过主内存来完成,线程、主内存、工作内存三者的交互关系如图所示: 这里所讲的主内存、工作内存与通常... 阅读全文
posted @ 2019-01-19 23:50 robin·张 阅读 (33) 评论 (0) 编辑
摘要:线程池的核心参数 corePoolSize:核心池的大小。在创建了线程池后,默认情况下,线程池中并没有任何线程,而是等待有任务到来才创建线程去执行任务,除非调用了prestartAllCoreThreads()或者prestartCoreThread()方法,从这2个方法的名字就可以看出,是预创建线程的意思,即在没有任务到来之前就创建corePoolSize个线程或者一个线程。默认情况下,在创建... 阅读全文
posted @ 2019-01-06 23:03 robin·张 阅读 (33) 评论 (0) 编辑
摘要:执行countdown的某个子线程可能会因为某些原因无法执行countdown,这样就会导致await线程一直阻塞下去。 在线程池中多次调用await方法,因为await方法会阻塞一段时间,有可能导致线程池可用线程被大量阻塞。 阅读全文
posted @ 2019-01-05 23:38 robin·张 阅读 (1092) 评论 (0) 编辑
共 6 页: 上一页 1 2 3 4 5 6 下一页