一 什么是事务,事务是怎么实现的
事务(Transaction)是指一系列操作的集合,这些操作要么全部成功,要么全部失败,确保数据的完整性和一致性。事务的基本概念是原子性、一致性、隔离性和持久性(ACID特性)。
事务的实现主要依赖于数据库管理系统(DBMS)提供的事务管理机制。实现事务的一般步骤如下:
- 事务开始:数据库系统启动一个事务,这个事务会在操作数据库时保持一致性。
- 事务执行:在事务开始后,进行一系列操作,如读写数据库记录。
- 事务提交:如果事务中的所有操作都成功,则提交事务,将所有修改保存到数据库。
- 事务回滚:如果事务中的某个操作失败,则回滚事务,撤销所有对数据库的修改,恢复到事务开始之前的状态。
二 事务的特性有哪些
原子性(Atomicity):事务是一个原子操作,要么完全执行,要么完全不执行。即使事务执行过程中发生错误,所有已完成的操作也会被撤销。
一致性(Consistency):事务必须使数据库从一个一致性状态变到另一个一致性状态。事务的执行不应破坏数据的一致性。
隔离性(Isolation):多个事务并发执行时,每个事务的操作对其他事务是不可见的。事务的隔离级别决定了事务之间的干扰程度。
持久性(Durability):一旦事务提交,其对数据库的修改就是持久的,即使系统发生故障也不会丢失。
三 锁的分类有哪些
共享锁(Shared Lock):允许多个事务同时读取数据,但不允许修改。持有共享锁的事务可以读取资源,但不能修改。
排他锁(Exclusive Lock):只有一个事务可以持有排他锁,并且可以修改数据。排他锁会阻止其他事务对该数据的读取和修改。
意向锁(Intention Lock):用于表示事务对某个数据行的锁定意图,通常与其他类型的锁配合使用。意向锁分为意向共享锁(IS)和意向排他锁(IX)。
行级锁(Row-Level Lock):锁定数据表中的某一行,粒度较小,通常提高并发性能。
表级锁(Table-Level Lock):锁定整张数据表,粒度较大,通常用于保证数据完整性,但可能影响并发性能。
乐观锁(Optimistic Locking):假设不会发生冲突,操作时不加锁,而是在提交时检查是否发生了冲突。常通过版本号或时间戳实现。
悲观锁(Pessimistic Locking):假设会发生冲突,操作时对数据加锁,以确保不会与其他事务发生冲突。
四 谈谈锁升级
锁升级原理:在锁对象的对象头里面有一个 threadid 字段,在第一次访问的时候 threadid 为空,jvm 让其持有偏向锁,并将 threadid 设置为其线程 id,再次进入的时候会先判断 threadid 是否与其线程 id 一致,如果一致则可以直接使用此对象,如果不一致,则升级偏向锁为轻量级锁,通过自旋循环一定次数来获取锁,执行一定次数之后,如果还没有正常获取到要使用的对象,此时就会把锁从轻量级升级为重量级锁,此过程就构成了 synchronized 锁的升级。
锁的升级的目的:锁升级是为了减低了锁带来的性能消耗。在 Java 6 之后优化 synchronized 的实现方式,使用了偏向锁升级为轻量级锁再升级到重量级锁的方式,从而减低了锁带来的性能消耗。
五 synrochnized用了CAS乐观锁,那怎么还是悲观锁呢
Synchronized 是一个悲观锁,因为它的并发策略是悲观的: 不管是否会产生竞争,任何的数据操作都必须要加锁、用户态核心态转换、维护锁计数器和检查是否有被阻塞的线程需要被唤醒等操作。
六 说一说JVM分代回收
JVM 的分代回收是垃圾回收机制的一种优化策略,将堆内存分为不同的代,以优化垃圾回收的效率。分代回收的主要思想是根据对象的生命周期来分类,以提高垃圾回收的效率。
JVM 通常将堆分为以下三个主要区域:
年轻代(Young Generation):包含 伊甸园区(Eden Space) 和 幸存区(Survivor Spaces)。新创建的对象首先分配到伊甸园区。经过一次或多次垃圾回收后,存活下来的对象会被移动到幸存区。
老年代(Old Generation):包含存活时间较长的对象。经过一定次数的年轻代垃圾回收后,仍然存活的对象会被移动到老年代。
永久代(Permanent Generation)(在 JDK 8 及之后版本中被元空间取代):存储类信息、方法信息等与类定义相关的数据。在 JDK 8 之前,永久代用于存储这些元数据;在 JDK 8 及之后版本中,使用元空间来替代永久代。
七 为什么进入了一个大对象,显示内存溢出,进行fullGC
大对象在 JVM 中分配时会直接进入老年代,而不是年轻代。这是因为大对象通常需要较大的内存空间,直接分配到年轻代可能导致频繁的年轻代垃圾回收。
当大对象导致老年代内存不足时,JVM 会尝试进行 Full GC(全堆垃圾回收),以回收老年代中的无用对象并释放空间。如果 Full GC 之后仍然无法释放足够的空间,可能会出现 java.lang.OutOfMemoryError: Java heap space
错误,表明 JVM 内存溢出。