理论知识

多线程的实现方式:
1.继承Thread类;
2.实现runnable接口;
3.实现callable接口通过futrueTask包装器来创建Thread线程;

是继承Thread类号还是实现runnable接口好
实现runnable接口好,因为继承的类就不能继承了

你在哪里使用到了多线程
主要体现到多线程提高程序效率,
比如一些批量发送短信,多下载等

线程常用的方法为什么在object中
1.这些方法存在与同步中
2.使用这些方法必须标识同步所属的锁
3.锁可以是任意对象,所以任意对象调用方法一定定义在Object类中

什么是线程安全
当多个线程访问同一代码,不会出现不确定的结果。

什么是多线程之间同步
当多个线程共享同一个资源,不会受到其他线程的干扰

什么是同步代码块
将可能发生线程安全的代码,给包括起来,只能让当前一个线程执行,被包裹的代码执行完成之后才能释放锁,之后才能让其他线程进行

多线程同步的几种方式?
1.使用同步代码块
2.使用同步函数
3.使用静态同步函数

同步代码块与同步函数的区别
同步代码可以绑定任意对象,而同步函数只能绑定该类对象听故事,static 同步函数只能绑定字节码类名.class,如果多个线程使用同一个锁的话,那么两者均可用,如果存在多个锁的话,只能使用同步代码块,开发推荐使用同步代码块。因为同步代码使用自定锁,同步函数使用this锁

HashMap的原理?
1.HashMap的数据结构(jdk1.8之前:)(数组+链表)底层是一个数组,数组的每一项是一个链表,每一次新建一个map其实就是新建了一个数组。
2.链表:每一次新建一个HashMap时,都会初始化一个table数组。table数组的元素为Entry节点。
3.HashMap在Map.Entry静态内部类实现中存储key-value,HashMap使用哈希算法,调用put会查询索引,存在就覆盖value,不存在就创建新的

servlet的生命周期
构造方法:创建servlet的时候调用
init方法:创建完servlet对象的时候调用,只调用一次
service方法:每次发出请求时调用
destroy方法:销毁servlet对象的时候调用

什么是多线程死锁
线程死锁是指两个或两个以上的线程持有对方所需要的资源,由于synchronized的特性,一个线程持有一个资源,或者说获得一个锁,在该线程释放这个锁之前,其他线程是获取不到这个锁的,而且会一直等下去,这就是线程死锁

如何停止一个正在允许的线程?
1.使用退出标志,
2.使用stop方法强行终止线程
3.使用interrupt方法中断线程。

什么是守护线程
java中有两种线程,一种是用户线程,一种是守护线程。当程序不存在或主线程停止,守护线程也会被停止,使用setDaemon(true)方法设置为守护线程

join()方法作用
join作用是让其他线程变为等待,只有当前线程执行完毕后,等待的线程才会被释放

线程的三大特性?
1.原子性:保证数据的一致性,线程安全。
2.可见性:对另一个线程是否课件
3.有序性:线程之间执行有顺序

Mybatis

什么是MyBatis
是一个实现了JPA规范用来连接数据库并对其进行curd操作的开源框架,他的底层就是jdbc封装的组件。

MyBatis的缓存
分为一级缓存和二级缓存,一级缓存放在session里面,默认就有,二级缓存放在命名空间里。默认是打不开的使用二级缓存属性,类需要实现Serializable序列化接口,

MyBatis的优点和缺点
优点:基于sql语句编程,相当灵活,不会对应用程序或者数据库的现有设计造成任何影响,SQL在Xml里,减少sql与程序代码的耦合,便于统一管理:提供Xml标签,支持编写动态sqll,并可重用
缺点:SQL语句的编写工作量较大,尤其当字段多,关联多表时,对开发人员编写SQL语句的功底有一定要求,SQL依赖数据库,导致数据库移植性差,不能随意更换数据库

MyBatis是如何进行分页的?分页插件的原理是什么
MyBatis使用RowBounds对象进行分页,也可以直接编写sql进行分页也可以使用MyBatis的分页插件
实现MyBatis提供的接口,实现自定义插件,在插件的拦截方法内拦截待执行的sql,然后重写sql

简述MyBatis的插件运行原理,以及如何编写一个插件
1.MyBatis仅可以编写针对ParameterHandler,ResultSetHandler,StatementHandler,Executor这四种接口的插件,MyBatis通过动态代理,为需要拦截的接口生成代理对象已实现接口方法拦截功能每当执行这四种接口对象方法时,就会进入拦截方法,具体就是InvocationHandler的invoke()方法,
2.实现MyBatis的Interceptor接口并重写intercept()方法,然后再给插件编写注解,指定要拦截哪一个接口的哪些方法即可,记住别忘了在配置文件中配置你编写的插件

MyBatis的好处是什么?
1.MyBatis把sql语句从java源程序中独立出来,放在单独的xml文件中编写,给程序维护带来了很大遍历
2.MyBatis封装了jdbc API的调用细节,并能自动将结果集转成java bean对象,大大简化了java数据库编程的重复工作
3.因为MyBatis需要自己编写sql,所以可,以灵活控制sql,能完成复杂查询

简述MyBatis的映射文件和内部数据的映射关系
MyBatis将所有xml配置信息都封装到ALL-IN-ONE重量级对象Configuration内部,在xml映射文件中

什么是MyBatis的接口绑定,有什么好处?
接口映射就是在MyBatis中任意定义接口,然后把接口里面的方法和sql语句绑定,我们直接调用接口方法就可以,这样比原来sqlSession提供的方法我们可以有更灵活的选择和设置

接口绑定有几种实现方式,分别是怎么实现的?
接口绑定有两种实现方式,一种是通过注解绑定,接口方法上面加上@Select@Update等注解里面包含sql语句来绑定
通过xml里面写来绑定,要指定xml映射文件里面的namespace必须为接口的全部路径

什么情况下用注解,什么情况下用xml绑定?
当sql简单,用注解,sql复杂用xml

MyBatis实现一对一有几种方式?具体怎么操作
有联合查询和嵌套查询,联合是几个表联合查询,只查询一次,通过resultMap里面配置association节点配置一对一的类就可以完成;
嵌套是先查一个表,根据这个表里面的结果的外键id去另一个表里面查询数据,通过associationp配置但另外一个表的查询通过select属性配置

MyBatis能执行一对一,一对多的关联查询吗?都有哪些实现方式,以及他们之间的区别?
MyBatis不仅能执行一对一,一对多,还可以多对一,多对多,多对一其实就是一对一,多对多其实就是多对一,只需要把selectOne改为selectList即可
关联对象查询:两种,一种是单独发送一个sql去查询关联对象,赋给主对象,另一种是嵌套查询,含义为使用join查询,一部分列是A对象的属性值,另外一部分列是关联对象B的属性值,好处是只发送一个sql

MyBatis里面动态sql是怎么设定的?用什么语法
一般通过if节点来实现,通过OGNL语法来实现,如果要写完整,必须配合where,trim节点,where就是节点内容插入where,trim节点是用来判断动态语句是以or and开始,那么会自动去掉

MyBatis是如何将sql执行结果封装为目标对象并返回的?都有哪些映射形式?
第一种使用resultMap,注意定义列名和对象属性名之间的映射关系
第二种使用sql列的别名功能,将列名书写为对象属性名,比如t_name as name

xml映射文件中,除了常见的select | insert | update | delete标签外,还有哪些标签?
resultMap,parameterMap,sql,include,selectKey,
动态sql九个标签

当实体类中的属性名和表中的字段名不一样,如果将查询的结果封装到指定pojo
1.通过sql语句中定义字段名的别名
2.使用resultMap来映射字段名与实体类属性名

模糊查询like语句该怎么写
1.java拼接通配符,通过#{}赋值
2.在sql语句中拼接通配符(不安全,会引发sql注入)

通常一个xml映射文件,都会写一个Dao接口与之对应,Dao的工作原理,是否可以重载
不能,因为dao寻找xml对应的sql的时候,权限名+方法名的保存和寻找策略。接口工作原理为jdk动态代理原理,运行时会为dao生成proxy,代理对象会拦截接口方法,去执行对应sql返回数据

MyBaits映射文件中,如果A标签通过include引用了B标签的内容,请问B标签能否定义在A标签的后面,还是说必须定义在A标签的前面?
虽然MyBatis解析xml映射文件是按照顺序解析的,但是,被引用的B标签依然可以放在任何地方,MyBatis解析A的时候,发现引用的B,那么他会把A标签标记为未解析状态,继续下面的标签,解析完所有的标签后,在解析A,这时候A标签就可以正常解析完成了

MyBatis的xml映射文件中,不同的xml映射文件,id是否可以重复
不同的xml映射文件,如果配置了namespace,那么id可以重复;如果没配置namespace那么id不能重复;namespace不是必须的,只是最佳实践而已。原因是namespace+id是作为Map

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

MyBaits中如何执行批处理?
使用BatchExecutor完成批处理

MyBatis都有哪些Executor执行器?他们之间的区别是什么?
MyBatis有三种基本的Executor执行器,SimpleExecutor,ReuseExecutor,BatchExecutor。
SimpleExecutor:每执行一次update或select,就开启一个Statement对象,用完立刻关闭Statement对象
ReuseExecutor:执行update或select,以sql作为key查询Statement对象,存在就使用,不存在就创建,用完后,不关闭Statement而是存在Map
BatchExecutor:完成批处理

MyBatis中如何指定使用哪一种Executor执行器?
在MyBatis配置文件中,可以指定默认的ExecutorType执行器类型,也可以手动给DefaultSqlSessionFactory的创建SqlSession的方法传递ExecutorType类型参数

MyBatis执行批量插入,能返回数据主键列表吗?
能,JDBC都能,MyBatis当然也能。

MyBatis是否可以映射Enum枚举类?
MyBatis可以映射枚举类,不单可以映射枚举类,MyBatis可以映射任何对象到表的一列上。映射方式为自定义一个TypeHandler,实现TypeHandler的setParameter()和getResult()接口方法。TypeHandler有两个作用,一是完成从javaType至jdbcType的转换,二是完成jdbcType至javaType的转换,体现为setParameter()和getResult()两个方法,分别代表设置sql问号占位符参数和获取列查询结果

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
如何获取自动生成的主键值?
配置文件设置usegeneratekeys为true

在mapper中如何传递多个参数
1.直接在方法中传递参数,xml使用、#{0},#{1}来获取
2.使用@Param注解:这样可以直接在xml文件中获取#{name}来获取

resultType和resultMap的区别?
1.类的名字和数据库相同时,可以直接设置resultType参数为Pojo类
2.若不同,需要设置resultMap将结果名字和Pojo名字进行转换

使用Mybatis的mapper接口调用时有哪些要求?
Mapper接口方法名要和mapper.xml中定义的每个sql的id相同
Mapper接口方法输入参数类型和mapper.xml中定义的每个sql的parameterType的类型相同
Mapper接口方法的输出参数类型和mapper.xml中定义的每个sql的resultType的类型相同
Mapper.xml文件中的namespace即是mapper接口的类路径。

MyBatis比IBatis比较大的几个改进是什么?
1.接口绑定,包括注解绑定sql和xml绑定Sql
2.动态sql由原来的节点配置变成了OGNL表达式
3.在一对一的时候引进了association,在一对多的时候引入了collection节点,不过都是在resultMap里面配置

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
IBatis和MyBatis的核心处理类分别叫什么?
IBatis里面核心处理类SqlMapClient,MyBatis里面核心处理类叫SqlSession

IBatis和MyBatis在细节上的不同有哪些?
1.在sql里面变量名有原来的#变量#,变成了#{变量}
2.原来的$变量编程了${变量}
3.原来在sql节点里面的class都换名字叫type
4.原来的queryForObject querForList变成了selectOne selectList 原来别名设置在映射文件里面放在了核心配置文件里、

简单介绍一下你对MyBatis的理解?
一个半ORM组件,MyBatis的着力点,在于sql与pojo之间的映射关系,也就是说MyBatis不会为程序员编写sql,具体的sql实现需要程序员编写,通过映射配置文件,将sql所需的参数,以及返回的结果字段映射到指定POJO。使用MyBatis提供的ORM机制,对业务逻辑实现人员而言,面对的是存粹的java对象,而对于具体的数据操作,MyBatis要求开发者编写具体的SQL语句。MyBatis以SQL开发的工作量和数据库移植性上的让步,为系统设计提供了更大的自由空间

MyBatis都有哪些Executor执行器?他们之间的区别是什么?
SimpleExecutor:没执行一次update/select都会新建Statement对象,用完立刻关闭
ReuseExecutor:执行update/select,以sql作为key查询Statement对象,存在就使用,不存在就新建,用完后不关闭Statement对象,而是放置在Map

MyBatis是否支持延迟加载?如果支持,它的实现原理是什么?
MyBatis仅支持association关联对象和collection关联集合对象的延迟加载,association指的是一对一,collection指的是一对多,MyBatis配置文件中可以配置是否用延迟加载:lazyLoadingEnabled=true|false
它的原理是,使用CGLIB创建目标对象的代理对象,当调用目标方法时,进入拦截方法,比如调用a.getB().getName(),拦截器invoke()方法发现a.getB()时null的,那么会单独发送实现保存好的sql,把B查询上来,然后调用a.setB(b),于是a的对象b属性就有值了,接着完成a,getB().getName()方法的调用。

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
MyBatis能执行一对一,一对多的关联查询吗?都有哪些实现方式
能,MyBatis不仅能执行一对一,一对多,还能执行多对一,多对多的关联查询,多对一查询其实就是一对一查询;多对多查询其实也就是一对多查询。
关联对象查询一共有两种实现方式,一种是单独发送一个sql去查询关联对象,赋给主对象,然后返回主对象,另一种是嵌套查询,嵌套查询的含义为使用join查询,一部分列是A对象,另外一部分是关联对象B的属性值,好处是只发以一个sql,就可以把主对象和其关联对象查询出来

MyBatis是如何将sql执行结果封装为目标对象并返回的?都有哪些映射形式?
第一种使用resultMap标签,注意定义列名与对象属性名之间的映射关系,
第二种是用sql的别名,将列名书写为对象名

MyBatis动态sql是做什么的?都有哪些动态sql?能简述一下动态sql的执行原理吗?
MyBatis动态sql能让我们在xml文件中,以标签的形式编写动态sql,完成逻辑判断和动态拼接sql的功能,
MyBatis提供了九种:trim | where | set | foreach | if | choose | when | otherwise | bind
执行原理:使用OGNL从sql参数对象中计算表达式的值,根据表达式的值动态拼接sql,以此来完成动态sql的功能

#{}和${}的区别是什么?
${}是Properties文件中的变量占位符,它可以用于标签属性值sql内部,属于静态文本替换,比如${driver}会呗静态替换为com.mysql,hdbc,driver

{}是sql参数占位符,MyBatis会将sql中的#{}替换为?号,在sql之前会使用,PreparedStatement的参数设置方法,按序给sql?号占位符设置参数值,比如ps.setInt(0,parameterValue),#{item.name}的取值方式为使用反射从参数对象中获取item对象的name属性值,相当于param.getItem(),getName()

介绍MyBatis的一级缓存和二级缓存的概念和实现原理?
一级缓存是sqlSession级别的,在操作数据库时需要构造sqlSession对象,在对象中有一个数据结构(hashMap)用于存储缓存数据。不同的sqlSession之间的缓存数据区域(HashMap)是互不影响的。
二级缓存是mapper级别的,也就是说可以多个sqlSeesion去操作同一个Mapper的sql语句,多个sqlSession可以公用二级缓存。

一级缓存工作原理:
当一个sqlSession对象去查询一条记录的时候,一级缓存会将其缓存到其数据结构中,当再次去使用相同条件查询的时候,直接从一级缓存中获取,不会去数据库中查询
当当前sqlSession执行了conmit(delete,update,insert)操作,一级缓存就会被清空,此后在有数据查询就会在一级缓存中找不到,然后就查询数据库中的数据然后再次放在一级缓存中,目前MyBatis默认开启一级缓存,一级缓存的作用,能适当减少数据库压力

二级缓存工作原理:
二级缓存底层是一个HashMap架构,二级缓存的作用域只在mapper级别,也就是说无论你多少个sqlSeesion去访问这个mapper,都会从缓存中获取到已有的数据,mapper对应的就是namespace,所以二级缓存是按照namespace进去区分的,如果这两个mapper文件的namespace相同,那么这两个mapper中查出来的数据都会存放在这个namespace中

配置二级缓存:
1.在Mybatis配置文件中加入

2.然后在具体mapper文件中增加

3.然后将对应的POJO类开启序列化

二级缓存的使用场景
访问频率且要求实时性不高(因为二级缓存可能涉及到关联mapper,一个mapper更新并不会影响另一个mapper)查询耗时,且实时性不高的SQL

二级缓存的缺点:
刷新信息就是全表刷新,只要有一个commit操作,整个缓存全部清空

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
当实体类中的属性名和表中的字段名不一样时有哪些处理方法?
1.在Mapper.xml中,写SQL的别名
2.在MyBatis全局配置文件中开启驼峰命名,前提是数据库中的字段是按照驼峰命名规则的两个单词之间加”_”命名的
3.在Mapper.xml映射文件中使用resultMap自定义映射关系

能简述一下动态SQL的执行原理吗?
第一部分:在启动加载解析xml配置文件的时候进行解析,根据关键标签封装成对应的handler处理对象,封装成sqlSession对象存在mappedStatement。

调用流程:
1.sqlSessionFactoryBuilder对builder对象时候,调用XMLConfigBuilder解析sqlMapConfig.xml配置文件,在解析过程中使用到了私有的mapperElement(XNode parent)方法
2.上面方法通过构建XMLMapperBuilder,获取到所有的配置mapper配置,在调用private void configurationElement(XNode context)方法进行解析mapper.xml通过void BuilderStatementFormContext(List

通常一个XML映射文件,都会写一个Mapper接口与之对应。请问这个Mapper接口的工作原理是什么?Mapper接口里方法,参数不同时,方法能重载吗?
Dao接口即Mapper接口。接口的权限名,就是映射文件中namespace的值,接口方法名,就是映射文件中Mapper的Statement的id值;接口方法内的参数,就是传递给sql的参数。
Mapper接口是没有实现类的,当调用接口方法时,接口权限名+方法名拼接字符串作为key值,可唯一定位一个MapperStatement。在MyBatis中,每一个,

Mapper接口绑定有几种方式,分别是怎么实现的?
接口绑定,就是MyBatis中任意定义接口,然后把接口里面的方法和sql语句绑定,我们直接调用接口方法就可以,这样比原来sqlSession提供的方法我们可以有更加灵活的选择和设置。
接口绑定有两种实现方式:
通过注解绑定:就是接口方法上面加上@Select,@Update等注解,里面包含Sql语句绑定;
通过xml绑定:里面写sql来绑定,在这种情况要指定xml文件中的namespace必须为接口的全部路径。当Sql语句比较简单的时候,用注解绑定,语句比较复杂的时候用xml绑定

在MyBatis中如何获取自动生成的主键值?
如果我们一般插入数据的话,我们想知道刚刚插入的数据的主键是多少,我们可以通过以下的方法来获取:
user对象插入到数据库后,新纪录的主键要通过user对象返回,通过user获取主键值
解决思路:
通过LAST_INSERT_ID()获取刚刚插入记录的自增值,在insert语句执行后,执行select LAST_INSERT_ID()就可以获取自增主键

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1.在Mapper中如何传递多个参数?
方法1:顺序传递法

{}里面数字代表你传入参数的顺序

这种方法不建议使用,sql层表达不直观,且一旦顺序调整容易出错
方法2:@param注解传递法

{}里面对应的是注解括号里面修饰的名称。

这种方法在参数不多的情况下还是直观的,
方法3Map传递法

{}里面的名称对应的是Map里面的key名称。

这种方法适合传递多个参数,且参数易变能灵活传递的情况
方法4 JavaBean传递发

{}里面的名称对应的是User类里面的成员属性

这种方法很直观,但需要建一个实体类,扩展不容易,需要添加属性,看情况使用

2.简述MyBatis的插件运行原理,以及编写一个插件?
运行原理:
mybatis可以编写针对Executor,StatementHandler,ParameterHandler,ResultSetHandler四个接口的插件,mybatis使用JDK动态代理为需要拦截的接口生成代理对象,然后实现接口的拦截方法,所以当执行需要拦截的接口方法时,会进入拦截方法(AOP面向切面编程的思想)
如何编写一个插件:
1.编写Intercepror接口实现类
2.设置插件的签名,告诉mybatis拦截哪个对象的哪个方法
3.最后将插件注册到全局配置文件中

3.mybatis连接数据库过程中数据库连接中断如何处理?
这里会涉及到网络通信的问题。在数据库连接中,connection操作可不是计算1+1这样的形式,它的底层是一个循环处理过程那么自然就跟时间扯上关系了,跟时间有关的设置有:max_idle_time,connect_timout。max_idle_time表明最大的空闲时间,超过这个时间socket就会关闭,这样操作系统会省心省力一些,毕竟操作系统维持一个socket也是花费不少精力的。connect_timeout表明链接超时时间,我们知道,网络环境就是跟潮水一样,一波一波的,总是在运动,即是数据库服务器活的杠杠的,但是因为网络堵塞,客户端依然连不上服务端,这个时候就要设置timeout,别一直傻等着。

55.在开发过程中,经常遇到插入重复的现象,这种情况该如何解决呢?
插入过程一般都是分两步的:先判断是否存在记录,没有存在则插入否则不插入。如果存在并发操作,那么同时进行第一步,然后大家都发现没有记录,然后都插入了数据造成重复的数据,
1.判断数据库是否有数据,有的话则不添加,没有则进行下面的内容,
2.想redis set key,其中只有一个操作a会成功,其他并发操作b和c会失败的,
3.上面set key成功的操作a,开始执行插入数据操作,无论是否插入数据成功,都会在最后del key
4.上面set key失败的操作b和c,sleep一下,然后再判断数据库是否有数据,有数据则不添加,没有数据则重复上面的set key,此时b和c在竞争,失败者则不添加,成功者则开始插入数据,然后无论插入成功还是失败都要del key,

56.事务执行过程中宏机的应对处理方式是什么?
不会自动执行,不会自动直接回滚,但是可以人工手动选择继续执行或者直接回滚,依据是事务日志。事务开启时,事务中的操作,都会先写入存储引擎的日志缓冲中,在事务提交之前,这些缓冲的日志都需要提前刷新到磁盘上持久化,这就是人们口中常说的”日志先行”(Write-Ahead Logging).

日志分为两种类型:redo log 和 undo log

方法1:顺序传递法#{}里面数字代表你传入参数的顺序这种方法不建议使用,sql层表达不直观,且一旦顺序调整容易出错方法2:@param注解传递法#{}里面对应的是注解括号里面修饰的名称。这种方法在参数不多的情况下还是直观的,方法3Map传递法#{}里面的名称对应的是Map里面的key名称。这种方法适合传递多个参数,且参数易变能灵活传递的情况方法4 JavaBean传递发#{}里面的名称对应的是User类里面的成员属性这种方法很直观,但需要建一个实体类,扩展不容易,需要添加属性,看情况使用

运行原理:mybatis可以编写针对Executor,StatementHandler,ParameterHandler,ResultSetHandler四个接口的插件,mybatis使用JDK动态代理为需要拦截的接口生成代理对象,然后实现接口的拦截方法,所以当执行需要拦截的接口方法时,会进入拦截方法(AOP面向切面编程的思想)如何编写一个插件:1.编写Intercepror接口实现类2.设置插件的签名,告诉mybatis拦截哪个对象的哪个方法3.最后将插件注册到全局配置文件中

在数据库链接中,connection操作可不是计算1+1这样的形式,它的底层时循环处理过程,即是循环处理过程那么自然就跟时间扯上关系了,跟时间有关的设置有max_idle_time,connect_timeout.max_idle_time表明最大的空闲时间,超过这个时间socket就会关闭,这样操作系统会省心省力一些,毕竟操作系统维持一个socket也是要花费不少精力的。connect_timeout表明连接的超时时间,我们知道,网络环境就是跟潮水一样,一波一波的,总是在波动,即是数据库服务器活的好好的,但是因为网络堵塞,客户端依然连不上服务器端,这个时候就要设置timeout,别一直傻等着

插入的过程一般都是分两步的:先是判断是否在记录,没有存在则插入否则不插入。如果存在并发操作,那么同时进行了第一步,然后大家都发现没有记录,然后都插入了数据从而造成数据的重复,解决插入重负的思路可以是这样的:

不会自动继续执行,不会自动直接回滚,但是恶意人工手动选择继续执行或者直接回滚,依据是事务日志。事务开启时,事务中的操作,但会先写入存储引擎的日志缓冲中,在事务提交之前,这些缓冲的日志都需要提前刷新到磁盘上持久化,这就是人们口中常说的日志先行,

日志分为两种:redo log 和 undo log

1.redo log

在系统启动的时候,就已经为redo log分配了一块连续的存储空间,以顺序追加的方式记录redo log,通过顺序io来改善性能。所有事务共享redo log的存储空间,他们的redo log按语句的执行顺序,一次交替的记录在一起。如下一个简单示例

记录1:

记录2:

记录3:

记录4:

此时如果数据库崩溃或者宕机,那么系统重启进行恢复时,就可以根据redo log中记录的日志,把数据恢复到崩溃前的一个状态。未完成的事务可以继续提交也可以选择回滚,这基于恢复的策略而定。

不是,凡是从线程思考问题的人,一般都是被Java技术的多线程思想锁禁锢了,其实在高性能服务器端开发底层往往考io复用来处理,这种模式就是:单线程+事件处理机制,在mysql里面往往有一个主线程,这是单线程(于Java中处处强调多线程思想有点不同),它不断的循环查看是否有socket是否有读写事件,如果有读写事件,再从线程池里面找个工作线程处理这个socket的读写事件,完事之后工作线程会回到线程池,所以:Java客户端中的一个Connection不是在MySQL中就对应一个线程来处理这个链接,而是由监听socket的主线程+线程池里面固定数目的工作线程来处理

Original: https://www.cnblogs.com/antlerJiudao/p/16357943.html
Author: Antler_九道街
Title: 理论知识

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/582978/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球