【MySQL从小白到高手】第六篇:事务和MySQL中的JDBC编程

前言

【MySQL从小白到高手】第六篇:事务和MySQL中的JDBC编程_第1张图片

目录

 事务~

什么是事务~

事务的原子性~

事务相关的面试题~ 

脏读~

不可重复读~

幻读~

MySQL中事务的隔离级别~ 

MySQL中的JDBC编程~ 

JDBC~ 

学习使用JDBC编程~ 

引入依赖~ 

导入到项目中~ 

编写代码~ 


 事务~

什么是事务~

事务诞生的目的就是为了把若干个独立的操作给打包成一个整体~~

案例:

1.你要去银行取钱~

2.取完钱要去和女神约会~

如果你不取钱你就没办法和女神约会~你只有有钱了才能带女神约会~但是如果你取完钱了~女神突然不想和你约会了~那你不是钱就白取了吗~存在银行里吃几分的利息不香嘛~

所以这就相当于是两个独立的操作给打包成一个整体~~

要么就是把两个操作都执行完~

要么就一个操作也不执行~

不需要存在~只执行了第一步~不执行第二步的中间状态~~

这种情况下就可以使用事务~

事务的原子性~

在SQL中~有的复杂的任务需要多个SQL来执行的时候~也同样需要打包在一起~

前一个SQL是为了给后一个SQL提供支持~如果后一个SQL不执行出问题了~前一个SQL也就失去了意义~~

这样的特点我们就叫做原子性:要么全都执行完,要么一个都不执行,任务不可以被再细分~~

案例:

转账~

A给B转500

账户表(name,   balance)

               A          1000

               B          1000 

给A这个账户余额减500

update  账户表  set  balance  =  balance  -  500  where  name  =  "A";

给B这个账户余额加500

update  账户表  set  balance  =  balance  +  500  where  name  =  "B";

那么在转账过程中,就可能会出现问题~

考虑一个极端情况:

执行完成第一个SQL之后,在执行第二个SQL之前,数据库崩了/程序崩了/机器崩了/机器断电了~

导致这里面的转账转出了一半这样一个中间状态~

显然这种中间状态是不科学的~~

而事务的原子性,就能避免出现这种中间状态~~

事务的原子性到底是咋避免的呢?

要么就全部执行~

要么就一个都不执行~~(其实该执行还是得执行,无法预知失败~当我们出现执行失败之后,由数据库自动执行一些"还原"性的工作,来消除前面的SQL带来的影响~看起来就好像一个都没执行一样~)

像这样还原性的工作我们把它称为"回滚"

你在执行到第二个SQL之前,你又没办法预知这次行动失败~~这个时候,就还是得先执行第一个SQL,执行完之后再执行第二个SQL,你只能试试看~

案例:

假设A给B转了500之后,接下来执行第二个SQL的时候出现了意外,导致无法执行~~

那么接下来数据库就会还原之前操作~~

也就是把之前改动过的数据给还原回去(上个操作是减,现在就是加,上个操作是乘,下个操作就是除)~

数据库是如何知道该还原成哪个值的呢?

数据库会拿个小本子,把执行过得每个操作都给记录下来~

既然都能还原,是不是就可以放心大胆的删除数据库了呢?

不可以~

数据库如果把这里面的所有操作都记得那么详细,也是要消耗大量的时间和空间的~

因此这个记录是必不会保存那么久~

如果你的数据库是经过了一年的时间沉淀出来的数据,但你的这些操作可能只记录了几天的.....

最近的这几天的操作可能也去能给你还原出来,但是要想把这一年中间零零散散的各种操作给它回溯回去,这种事其实就没那么容易了~

如果你想把整个库都还原,这事还是得依赖于备份~~

不要对删库这种行为跃跃欲试~~~no zuo no die why you try~~

备份其实更多的是为了应对一些突发情况,硬盘坏了.....(出现的概率比删库的概率其实更高,就不细讲了)~~

事务相关的面试题~ 

谈谈事务的基本特征~

四个基本特征~

1.原子性:

把这些操作打包成一个整体,要么全都执行要么就一个都不执行~

2.一致性~

在事务执行之前和执行之后,数据库中的数据都是合理合法的~

例如:你转完账之后,不能出现这种账户为负数的情况~或者出现小数的情况

3.持久性~

事务一旦提交之后,数据就被持久性存储起来了~数据就写入硬盘了~

4.隔离性~

​​​​​​隔离性描述的是,事务并发执行的时候,产生的情况!!!

并发编程,是当下最主要的一个编程方式~~

写出来的代码,是并发式执行的~~(通俗点讲就是一心两用~)

但是人脑特别不擅长一心两用,而计算机特别擅长~~

计算机擅长并发,也是迫不得已~~

大家应该都听过"duoheCPU"

单个核心的提升能力已经快达到瓶颈了~~CPU是通过在硅晶圆上进行刻蚀电路(光刻机)制作出来的,很难很难做出来~

为什么难做呢?因为要提高算力,就得让单个的电路模块尽量小~能无限小嘛?显然不可能~

当物体小到一定程度的时候,经典力学就已经失效了,量子力学开始监管~

当我们并发执行多个事务,尤其是这多个事务都在尝试修改/读取同一份数据~

这个时候就同一出现一些问题~

事物的隔离性,就是在解决这样的问题~~

并发执行事务可能带来的问题~~

脏读~

有一天,我在写代码~~写一个课后作业的代码~~

比如:我在写代码中写了一个student类~~在我写代码的过程中,有一个同学,在后面瞄了我屏幕,看到了我写的代码(看到了我写的代码里面有一个student类,有一些属性....)看完之后,他就走人了~~

然后后面我把代码给改了~~

这个时候就意味着他在这里瞄的一眼,瞄到的并不是一个最终版本的数据.而是一个中间过程的数据~~这里可能最终会被修改成别的值~~

像这样的一个情况就成为"脏读"问题~

事务A在对某个数据进行修改,修改的同时,事务B去读取了这个数据.此时事务B读到的很可能是一个"脏数据"(这个数据是一个临时的结果,而不是最终的结果)

那么如果事务B拿着这个"脏数据"在进行一些后续操作很有可能就会出现问题.

出现脏读问题,原因就是事务和事务之间,没有进行任何的隔离~~如果加上一些约束限制,就可以有效的避免脏读问题~

如何处理脏读:给写操作加锁~

在修改的过程中,别人不能读了(加锁状态)

等修改完了之后,别人才能读(解锁状态)

和同学约好~不用着急窥屏~

我写完的作业会提交到码云上,你来看我码云上的代码~~

码云上就是我修改完毕的代码~~这样,同学读到的数据就不再是中间数据了~

一旦加上了写锁之后,就意味着事务之间的隔离性就高了,并发性就降低了

不可重复读~

【MySQL从小白到高手】第六篇:事务和MySQL中的JDBC编程_第2张图片

 我在写代码~~朋友在通过我的码云来读取代码~~

我开始写代码,写完之后提交码云,就可以把这个操作视为一个事务

同学在我提交之后开始读代码~

按照刚才针对脏读问题的约束.

给写操作进行了加锁,朋友要等我提交之后才能开始读~

但是在朋友读的过程中我可不可以继续写代码呢

当然可以

所以我可能要对代码进行修改

所以我又开始写代码,提交码云

这个时候在我第二次修改代码到提交之前,朋友读到的是我写的第一个版本的代码,在我修改完毕重新上传之后读到的又是我改的第二个版本的代码~

这样的话就出现了另外的问题:

在一个事务中,包含了多次的读操作,这多次的读操作读出来的结果不一致~

刚才约定的是,写的过程中不能读,没说读的过程中不能写~

这样的问题我们就叫做"不可重复读"

如何解决?

刚才这个问题就好比说:朋友在通过码云读代码~~随便刷新了一下,发现代码变了....(又得重新整理)

所以我们再做一个约定~~之前咱么约定的是,你修改的时候我不能读,现在再约定一下,我读的时候,你也别修改~~

给读操作也加锁了~~

意味着我必须得等朋友把代码读完了,才能进行修改~~

通过给读操作也加锁,就解决了不可重复读的问题~

此时事务的并发性又降低了,隔离性又提高了~~

并发性和隔离性二者不可得兼~~

到底要跑的快还是跑的对?

这件事需要看情况进行取舍了~~

幻读~

我开始写代码,提交代码~

朋友读代码

此时我想写代码或者修改代码就得等朋友读完代码~

等的这段时间我该干嘛呢?不能干等着把,带薪摸鱼?不可取

所以我就决定去写另外一个代码,再提交码云~

【MySQL从小白到高手】第六篇:事务和MySQL中的JDBC编程_第3张图片

 注意:事务虽然在提交隔离性的时候要进行一系列加锁,但是这个锁也不是把整个数据库都给锁定了~

还可以改其他的表,甚至说改这个表的其他的行~~

假设朋友在读我写的代码JavaA,在读的过程中,发现代码数量变了~~

本来只有一个JavaA的,现在有多了一个JavaB~

这种就被称为"幻读"问题

一个事务执行的过程中进行了多次查询,多次查询的结果集不一样了~~(多了一条或者少了一条)

这个操作算是一种特殊的不可重复读~~

解决幻读问题:彻底串行化执行~~

朋友和我说好,他读代码的时候,我就赶紧摸鱼,不要写任何代码了......

这种就是隔离性最高,并发程度最低,数据最可靠,速度最慢~

并发(更快)和隔离(更准)是不可兼得~~

就可以根据实际需要来调整数据哭的隔离级别~~

通过不同的隔离级别,也就控制了事务之间的隔离性,也就控制了并发程度~~

MySQL中事务的隔离级别~ 

1.read uncommitted:允许读取未提交的数据,并发程度最高,隔离程度最低,会引入脏读+不可重复读+幻读问题~~

2.read committed:只允许读取提交之后的数据,相当于写加锁,并发程度降低了一些,隔离程度提高了一些,解决脏读,会引入不可重复读+幻读~

3.repeatable read:相当于给读和写都加锁,并发程度又降低了,隔离程度又提高了,解决了脏读和不可重复读,会引入幻读

4.serializable:串行化,并发程度最低(串行执行),隔离程度最高,解决了脏读,不可重复读,幻读问题,但执行速度最慢~

这几个隔离级别我们可以通过修改my.ini这个配置文件,来设置当前的隔离级别~

根据实际需求场景,来决定使用哪种隔离级别~~

MySQL中的JDBC编程~ 

实际开发程序必要过程~

首先MySQL是一个客户端-服务器结构程序~

【MySQL从小白到高手】第六篇:事务和MySQL中的JDBC编程_第4张图片

黑框框只是一个官方提供的客户端,官方也允许程序猿自己实现MySQL的客户端,并且MySQL提供了一组API(计算机行业中经常见到的术语~Application Programming  Interface:应用程序编程接口,MySQL提供了一些方法/类,供程序猿直接使用)来支持程序猿实现这样的客户端~~自己实现的客户端可以根据需要来完成一些更具体的增删改查功能~~

咱们很容易的能够实现一个MySQL客户端

但是并不容易实现MySQL服务器.....MySQL服务器是本体,非常复杂....

JDBC~ 

数据库又不是只有MySQL~~

还有Oracle,SQL sever,SQLite......

MySQL提供了API

Oracle也提供了API......

MySQL提供的API和Oracle提供的API是不是一样的?

显然这些不同的数据库是出自不同厂商之手~

而且关于数据库API的约定,并没有一个业界统一的标准~~

Java一看,不乐意了~~Java表示我诞生就是为了跨平台(这是Java诞生的初衷)

Java就搞了一个大一统的方案:JDBC~

Java约定了一组API:称为JDBC

这组API里面就包含了一些类和一些方法,通过这些类和方法来实现数据库的基本操作~~

让JDBC和这些不同的数据库对接,再由各个厂商,提供各自的"数据库驱动包(通过驱动包把自己的API转换成JDBC风格的,两者对接在一起)",来和JDBC的API对接~~

程序猿只需要掌握这一套JDBC API就可以操作各种数据库了~~

总结一句话:啥是JDBC,就是一组类和方法~~会了这个,就可以操作所有的数据库~~

学习使用JDBC编程~ 

创建项目~

1.打开idea:  点击new project

【MySQL从小白到高手】第六篇:事务和MySQL中的JDBC编程_第5张图片

 点击之后

【MySQL从小白到高手】第六篇:事务和MySQL中的JDBC编程_第6张图片

 

设置名字,目录,点击Create

【MySQL从小白到高手】第六篇:事务和MySQL中的JDBC编程_第7张图片

引入依赖~ 

 JDBC编程需要用到MySQL的驱动包(驱动包就是把MySQL自身的API给转换成JDBC风格的)

驱动包是MySQL官方提供的~~

下载驱动包(从MySQL官方网站~~但是MySQL被Oracle收购了,Oracle的官方做的不太行.....)

更好的选择可以去maven(Java中构建工具)中央仓库~

每次装个软件(第三方库)都需要去官网上找,就比较麻烦,就可以把这些第三方库给汇总起来,统一放到一个地方,中央仓库来下载~

中央仓库就相当于手机的应用商店~

下载地址:www.mvnrepository.com

搜索MySQL第一个就是

【MySQL从小白到高手】第六篇:事务和MySQL中的JDBC编程_第8张图片

选择版本

【MySQL从小白到高手】第六篇:事务和MySQL中的JDBC编程_第9张图片

因为我都MySQL版本是5系列的,所以jdbc版本要和mysql版本对应~~

如果你MySQL版本是8系列,就得用8系列的jdbc驱动~~

选一个版本点击一下:

【MySQL从小白到高手】第六篇:事务和MySQL中的JDBC编程_第10张图片

点击之后就会进入到这个界面

点击标红的地方就会下载驱动包

下载之后就会得到一个jar这样的文件(就相当于.zip这样的压缩包一样)

jar里面就是一些其他人写好的.class文件~

【MySQL从小白到高手】第六篇:事务和MySQL中的JDBC编程_第11张图片

导入到项目中~ 

创建个目录,随便起个名字,例如叫做lib~

【MySQL从小白到高手】第六篇:事务和MySQL中的JDBC编程_第12张图片

 【MySQL从小白到高手】第六篇:事务和MySQL中的JDBC编程_第13张图片

 【MySQL从小白到高手】第六篇:事务和MySQL中的JDBC编程_第14张图片

 把刚才下载的jar文件拷贝到刚才的目录中去~

【MySQL从小白到高手】第六篇:事务和MySQL中的JDBC编程_第15张图片

 【MySQL从小白到高手】第六篇:事务和MySQL中的JDBC编程_第16张图片

 

右键刚才的目录,有一个选项,叫做add as library,点击这个选项才能把这个jar引入到项目中.

此时项目才会从jar里面读取内部的.class~否则,代码就找不到jar中的一些类了

【MySQL从小白到高手】第六篇:事务和MySQL中的JDBC编程_第17张图片

【MySQL从小白到高手】第六篇:事务和MySQL中的JDBC编程_第18张图片 

 【MySQL从小白到高手】第六篇:事务和MySQL中的JDBC编程_第19张图片

这样就成功了 

编写代码~ 

下一章来如何编写代码~

【MySQL从小白到高手】第六篇:事务和MySQL中的JDBC编程_第20张图片

 

你可能感兴趣的:(mysql,数据库,database,java,sql)