MYSQL知识点及优化 | 面试前专攻

1、事务

一、实例介绍

user表数据html

在这里插入图片描述

user1表数据java

在这里插入图片描述

public static void main(String[] args) {
    Connection connection = null;
    PreparedStatement preparedStatement = null;
    try {
        Class.forName("com.mysql.cj.jdbc.Driver");
        String url = "jdbc:mysql://localhost:3306/test?serverTimezone=UTC";
        connection = DriverManager.getConnection(url,"root","root");
        // 禁止jdbc自动提交事务
        //connection.setAutoCommit(false);
        preparedStatement = connection.prepareStatement("update user set money = money-? where id= ?");
        preparedStatement.setInt(1,10);
        preparedStatement.setInt(2,1);
        preparedStatement.executeUpdate();
        //抛出异常
        String str = null;
        if(str.equals("")){

        }
        preparedStatement = connection.prepareStatement("update user1 set money = money+? where id = ?");
        preparedStatement.setInt(1,10);
        preparedStatement.setInt(2,1);
        preparedStatement.executeUpdate();
        // 提交事务
        //connection.commit();
    } catch (Exception e) {
        e.printStackTrace();
            // 回滚事务
            // try {
            // connection.rollback();
            //} catch (SQLException e1) {
            // e1.printStackTrace();
            //}

    }finally {
        try {
            preparedStatement.close();
            connection.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}
复制代码

由上述代码可知:操做一执行成功后,代码出现异常,致使操做二没法进行 但转帐过程是一个事务:操做应要么所有成功,要么所有失败mysql

所以咱们应该:
一、禁止jdbc自动提交事务
connection.setAutoCommit(false);
二、在两条SQl语句执行完以后提交事务
connection.commit();
三、若是有异常则回滚事务
 catch (Exception e) {
       e.printStackTrace();
       // 回滚事务
       try {
           connection.rollback();
       } catch (SQLException e1) {
           e1.printStackTrace();
  }
复制代码

关于事务提交、回滚的理解:sql

在这里插入图片描述

二、特性(ACID)

事务的原子性数据库

<数据库事务不可分割的单位,要么都作,要么都不作>
 	事务是最小单元,不可再分,要么所有执行成功,要么所有失败回滚。
复制代码

事务的一致性markdown

<事务的操做不会改变数据库的状态,比方说惟一约束>
  一致性是指事务必须使数据库从一个一致的状态变到另一个一致的状态,
   也就是执行事务以前和以后的状态都必须处于一致 的状态。
   不一致性包含三点:脏读,不可重复读,幻读
复制代码

事务的隔离性并发

<事务是相互不可见的>
	隔离性是指当多个用户并发访问数据库时,好比操做同一张表时,数据库为每个用户开启的事务,不能被其余事务的操做所 干扰,多个并发事务之间要相互隔离
复制代码

事务的持久性oop

<事务一旦提交,即便宕机也是能恢复的>
	DBMS(数据库管理系统)对数据的修改是永久性的。
复制代码

三、分类

blog.csdn.net/cpongo6/art…性能

四、隔离级别

www.cnblogs.com/wyaokai/p/1…优化

mysql默认的事务隔离级别为repeatable-read

未提交读

读未提交,即可以读取到没有被提交的数据
   因此很明显这个级别的隔离机制没法解决脏读、不可重复读、幻读中的任何一种。
复制代码

已提交读

读已提交,即可以读到那些已经提交的数据
   天然可以防止脏读,可是没法限制不可重复读和幻读
复制代码

可重复读

可重复读,读取了一条数据,这个事务不结束,
   别的事务就不能够改这条记录,这样就解决了脏读、不可重复读的问题,
复制代码

串行化

串行化,多个事务时,只有运行完一个事务以后,才能运行其余事务。
复制代码

在这里插入图片描述

补充:

  一、事务隔离级别为读提交时,写数据只会锁住相应的行

  二、事务隔离级别为可重复读时,若是检索条件有索引(包括主键索引)的时候,默认加锁方式是next-key 锁;若是检索条件没有索引,更新数据时会锁住整张表。一个间隙被事务加了锁,其余事务是不能在这个间隙插入记录的,这样能够防止幻读。

  三、事务隔离级别为串行化时,读写数据都会锁住整张表

  四、隔离级别越高,越能保证数据的完整性和一致性,可是对并发性能的影响也越大。

  五、MYSQL MVCC实现机制参考连接:blog.csdn.net/whoamiyang/…

  六、关于next-key 锁能够参考连接:blog.csdn.net/bigtree_372…

五、并发问题

一、脏读:事务A读取了事务B更新的数据,而后B回滚操做,那么A读取到的数据是脏数据

二、不可重复读:事务 A 屡次读取同一数据,事务 B 在事务A屡次读取的过程当中,对数据做了更新并提交,致使事务A屡次读取同一数据时,结果 不一致。

三、幻读:系统管理员A将数据库中全部学生的成绩从具体分数改成ABCDE等级,可是系统管理员B就在这个时候插入了一条具体分数的记录,当系统管理员A改结束后发现还有一条记录没有改过来,就好像发生了幻觉同样,这就叫幻读。    小结:不可重复读的和幻读很容易混淆,不可重复读侧重于修改,幻读侧重于新增或删除。解决不可重复读的问题只需锁住知足条件的行,解决幻读须要锁表   

2、锁

blog.csdn.net/lzx_victory…

一、Lock

二、latch

<轻量级锁,锁的时间很是短,用来锁临界资源>

三、一致性的非锁定读

四、一致性锁定读

五、死锁

3、sql优化原则

一、选择须要优化的sql

二、Explain和Profile入手

三、永远小结果集驱动大的结果集

四、在索引中完成排序

五、使用最小Columns

六、使用最有效的过滤条件

七、避免复杂的join和子查询

4、join的原理

5、执行流程计划与执行明细

6、执行流程

7、表结构对性能的影响

8、索引

相关文章
相关标签/搜索