MySQL之ACID实现原理1. MySQL事务
事务是一组操作的集合,它是一个不可分割的最小的工作单位,事务会把所有的操作作为一个整体一起向系统提交或者撤销操作请求,即这些操作要么同时成功,要么同时失败。
MySQL中关于事务操作的命令如下:
select @@autocommit; # 查看事务的提交方式set @@autocommit; # 设置事务的提交方式commit; # 提交事务rollback; # 回滚事务start transaction; # 开启事务begin; # 开启事务
2. 事务四大特性事务的四大特性其实就是我们常说的ACID,对于它们的解释如下:
(1)原子性(atomicity):一个事务必须被视为一个不可分割的最小工作单元,整个事务中的所有操作要么全部提交成功,要么全部失败回滚。事务是操作的最小单位,不可再分。
(2)一致性(consistency):数据库总是从一个一致性转换到另一个一致性。即事务发生前和事务发生后,数据的完整性必须保持一致。
(3)隔离性(isolation):多个事务之间的数据是相互隔离的,当并发访问数据库时,一个正在执行 ...
Spring
未读Spring之事务原理篇1. Spring事务的实现方式
编程式事务 : 在代码中硬编码(不推荐使用) : 通过 TransactionTemplate或者 TransactionManager 手动管理事务,实际应用中很少使用,但是对于你理解 Spring 事务管理原理有帮助。
声明式事务 : 在 XML 配置文件中配置或者直接基于注解(推荐使用) : 实际是通过 AOP 实现(基于@Transactional 的全注解方式使用最多)
另外,在官方文档中也有关于Spring事务的实现原理的简单概述:
关于Spring框架的声明性事务支持,最重要的概念是这种支持是通过 AOP代理 实现的,而且事务advice是由元数据(目前是基于XML或注解)驱动的。AOP与事务元数据的结合产生了一个AOP代理,它使用 TransactionInterceptor 与适当的 TransactionManager 实现来驱动围绕方法调用的事务。
@Transactional 通常与 PlatformTransactionManager 管理的线程绑定的事务一起工作,将一个事务暴露给当前执行线程内的 ...
Spring
未读Spring之如何选择事务因为博主之前的实习经历中有使用编程式事务的经历,因为当时是同事给的方案,所以并没有深究为什么不用编程式事务,最近刚好在面试,有面试官问到:为什么不使用声明式事务?因为现在基本很多场景下我们都是直接使用@Transactional注解直接开启事务,所以很少会去使用编程式事务。
所以今天我们就借助这个机会好好来总结一下应该如何选择。
Spring官方文档中对事务的描述如下:
翻译文档链接:传送门
Spring解决了全局和局部事务的弊端。它让应用开发者在任何环境下都能使用一个一致的编程模型。你只需写一次代码,它就可以在不同的环境中受益于不同的事务管理策略。Spring框架同时提供声明式和编程式事务管理。大多数用户更喜欢声明式事务管理,我们在大多数情况下都推荐这样做。
通过编程式事务管理,开发人员使用Spring框架的事务抽象,它可以在任何底层事务基础设施上运行。通过首选的声明式模型,开发人员通常很少或不写与事务管理有关的代码,因此,不依赖于Spring框架的事务API或任何其他事务API。
下面我们就带大家来学习一下什么是声明式事务和编程式事务。
1. 编程式事 ...
JVM之带你认识Full GC一. 主要的GC形式JVM在进行GC时,并非每次都对所有内存区域进行垃圾回收,大部分回收的都是指新生代。
针对Hotspot VM的实现,它里面的GC按照回收区域又分为两大种类型:一种是部分收集(Partial GC),一种是整堆收集(Full GC)。
部分收集(Partial GC):不是完整收集整个Java堆的垃圾收集。其中又分为:
新生代收集(Minor GC / Young GC):只是新生代的垃圾收集
老年代收集(Major GC / Old GC):只是老年代的圾收集。
目前,只有CMS GC会有单独收集老年代的行为。
注意,很多时候Major GC会和Full GC混淆使用,需要具体分辨是老年代回收还是整堆回收。
混合收集(MixedGC):收集整个新生代以及部分老年代的垃圾收集。
目前,只有G1 GC会有这种行为
整堆收集(Full GC):收集整个java堆和方法区的垃圾收集。
1.1 新生代GC(Minor GC)触发机制
当新生代空间不足时,就会触发 ...
Java
未读Java并发之线程池详解一、线程池概述1.1 什么是线程池程序运行的本质就是占用系统的资源,优化资源的使用从而衍生出来的技术就是池化技术。
线程池其实就是一种多线程的处理方式,处理过程中可以将任务添加到队列中,然后创建线程处理这些任务。
线程池的优点:
降低资源消耗。线程池通过复用利用已经创建的线程来降低线程的创建和销毁造成的消耗。
提高响应速度。当有新的任务到达时,如果线程池中有空闲状态的线程,任务可以不需要等待线程的创建就可以立即执行。
提高线程的可管理性。线程是一种稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以对线程进行统一的分配和管理。
1.2 线程池的执行过程线程池的处理流程如下:
线程池判断核心线程池里的线程是否都在执行任务。
如果不是,则创建一个新的工作线程来执行任务。
如果核心线程池里的线程都在执行任务,则进入下一个流程。
线程池判断工作队列是否已满。
如果工作队列没有满,则将新提交的任务存储在这个工作队列里面。
如果工作队列满了,则进入下个流程。
线程池判断线程池的线程是否都处于工作状态。
如果没有,则创建一个新的工 ...
MySQL
未读MySQL优化之索引下推一、概念索引条件下推(Index Condition Pushdown),简称ICP。MySQL5.6新添加,用于优化数据的查询。
比如说有这样的场景:
有些搜索条件中虽然出现了索引列,但却不能使用到索引,比如下边这个查询:
SELECT * FROM table WHERE key1 = ‘z’ AND key1 LIKE ‘%a’;
其中的 key1 = 'z' 可以使用到索引,但是 key1 LIKE '%a' 却无法使用到索引,在以前版本的 MySQL 中,是按照下边步骤来执行这个查询的:
先根据 key1 = 'z' 这个条件,从二级索引 idx_key1 中获取到对应的二级索引记录。
根据上一步骤得到的二级索引记录中的主键值进行回表,找到完整的用户记录再检测该记录是否符合
key1 LIKE '%a' 这个条件,将符合条件的记录加入到最后的结果集。
但是虽然key1 LIKE '%a'不能组成范围区间参与 range 访问方法的执行,但这个条件毕竟只涉及 ...
MySQL
未读MySQL优化之SQL优化详解在应用的开发过程中,由于初期数据量小,开发人员写SQL语句时更重视功能上的实现,但是当应用系统正式上线后,随着生产数据量的急剧增长,很多SOL语句开始逐渐显露出性能问题,对生产的影响也越来越大,此时这些有问题的SQL语句就成为整个系统性能的瓶颈,因此我们必须要对它们进行优化。
优化SQL的步骤当面对一个有SOL性能问题的数据库时,我们应该从何处入手来进行系统的分析,使得能够尽快定位问题SOL并尽快解决问题,我将带大家一起学习这个过程。
1. 了解SQL执行频率MySQL客户端连接成功后,通过show [session|global] status命令可以提供服务器状态信息。通过如下指令,可以查看当前数据库的INSERT、UPDATE、DELETE、SELETE的访问频次:
show global status like 'Com_______'; //注意:七个下划线代表七个字符
Com_xxx表示每个xxx语句执行的次数,我们比较关心的是以下几个统计参数:
Com_select:执行SELECT操作的次数,一次查询只累加1;
...
Java
未读Java并发之死锁详解死锁(1)概念① 进程死锁
指两个或者两个以上的进程在执行过程中,因争夺资源而造成的一种互相等待的现象,由于这些进程都无法继续运行,导致没有一个进程可以被唤醒,就形成了进程死锁。
② 线程死锁
多个线程同时被阻塞,他们中的一个或者全部都在等待某个资源被释放,由于线程被无限期的阻塞,所以程序不可能正常终止,线程就会陷入互相等待的状态,就产生了线程死锁。
(2)产生死锁的条件
互斥条件:当资源被一个线程占有时,其他线程不能使用
请求和保持条件:当资源请求者在请求其他的资源的同时保持对原有资源的占用
不可抢占条件:资源请求者不能强制从资源占有者手中夺取资源,资源只能由资源占有者主动释放
循环等待条件:即存在一个等待的队列:P1占有P2的资源,P2占有P3的资源,P3占有P1的资源,这就形成了一个等待环路
(3) 如何排查死锁
windows
我们首先使用Java的进程查看命令来查看Java进程运行的情况jps,如图
然后使用对应的PID去排查,使用的命令为jstack,控制台会给出死锁的详细信息。
Linux
Linux 下可以通过 top 先定位到 CPU ...
Java并发之创建线程的几种方式在面试中,我们会被经常问道:“ Java中的线程创建有几种方式? ”
这是一道很经典的八股文了,当然对于我们来说不在话下,答:“三种,继承Thread类、实现Runnable接口、实现Callable接口”。
是不是很简单,确实,但是你以为只有这三种方式吗?哈哈,那可不一定。
像一些其他的线程池啊,CompletableFuture类等,也都可以创建出线程。
不过,这些方式呢,其实并没有真正的创建出线程。
准确来说,这些都是属于在Java代码中使用多线程的不同方式。
严格来说,Java只有一种方式可以创建线程,就是通过new Thread().start()创建。
其实这样我们就能明白,以上的很多方式,其实底层都是通过new 来创建线程的,并且提供给用户使用。
关于这个问题,我们可以看这篇文章,其中有着很详细的解释:
大家都说Java有三种创建线程的方式!并发编程中的惊天骗局!
Java并发之synchronized详解一、synchronizedsynchronized是Java中的关键字,是一种同步锁,他修饰的对象有以下几种:
修饰一个代码块,被修饰的代码块称为同步方法块,其作用的范围是使用大括号括起来的代码,作用的对象是调用这个代码块的对象。
修饰一个方法,被修饰的方法称为同步方法,其作用的范围是整个方法,作用的对象是调用这个方法的对象。
修饰一个静态的方法,其作用的范围是整个静态方法,作用的对象是这个类的所有对象。
修饰一个类,其作用的范围是synchronized后面括起来的部分,作用的对象是这个类的所有对象。
无论synchronized关键字加在方法上还是对象上,
如果它作用的对象是非静态的,则它获取的是对象;
如果它作用的对象是一个静态方法或一个类,则它获取的锁是对于类的,该类的所有对象持有同一把锁。
实现同步是要很大的系统开销作为代价的,甚至可能造成死锁,所以尽量避免不必要的同步控制。
二、synchronized原理(1)对象头在JVM中,对象在内存中存储的布局可以分为三个区域,分别是对象头、示例数据以及填充数据。
对象头:在Ho ...