博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
mysql 事务管理
阅读量:3905 次
发布时间:2019-05-23

本文共 3034 字,大约阅读时间需要 10 分钟。

文章目录

什么是事务

简单的来说,事务是一组业务操作,这些业务操作要么全部执行成功,要么全部执行不成功。

事务的特性

事务具有四个特性

  • 原子性:事务是一个不可分割的基本单位,事务的业务操作要么全部成功,要么全部不成功
  • 一致性:事务执行前后数据的完整性必须一致
  • 隔离性:多个事务,事务的隔离性是指多个用户并发访问数据库时,一个用户的事务不能被其它用户的事务所干扰,多个并发事务之间数据要相互隔离。
  • 持久性:持久性是指一个事务一旦被提交,它对数据库中数据的改变就是 永久性的,接下来即使数据库发生故障也不应该对其有任何影响。

mysql 中常见事务操作

开启事务

start TRANSACTION;# orBEGIN;

提交事务

commit

回滚

rollback

关闭自动提交事务

SET autocommit = 0;

提交事务演示事例

现有一个数据库表,其中的数据如下:

在这里插入图片描述
为了更好的呈现出实验效果,我又在终端连接到了mysql数据库
所以说现在一共有两个连接,一个是mysqlworkbench,一个是终端。
我在终端开启事务并向表中插入一条语句,然后在终端查看表中的数据
注意:我没有提交事务
在这里插入图片描述
可以看到,在终端中显示插入数据成功。
下面我们看一下mysqlworkbench中的表情况:
在这里插入图片描述
可以看到,workbench中并没有新插入的行,这是由于没有提交事务造成的。
我们再在终端提交事务,然后再次查看workbench中的数据。
在这里插入图片描述
发现插入成功,这说明一旦开启事务,需要手动commit,不然sql语句是不会生效的。
我们也可以设置关闭自动提交事务来避免每次都要手动开启事务,这样我们每次写完sql语句都需要手动commit才能使sql语句生效。
在这里插入图片描述
这里我设置关闭自动提交事务,然后执行一条更新语句,之后查询数据发现更新成功。
下面我们看下workbench中的情况。

在这里插入图片描述

发现并没有更新成功,之后我们commit。
在这里插入图片描述
发现更新成功。所以说我们需要手动提交才能生效。

事务隔离问题

脏读: 一个事务读到另一个事务未提交的数据

不可重复读: 一个事务读到另一个事务已提交的数据(update)

虚读(幻读): 一个事务读到另一个事务已提交的数据(insert)

mysql 事务隔离级别

read uncommitted(读未提交): 3个问题都没解决

read committed(读已提交):解决脏读

repeatable read(可重复读):解决脏读,不可重复读

serializable(串行化):都解决,单事务处理模式

注意:隔离级别越高,则性能越差

解决脏读

在这里说一下查看数据库的隔离级别:

select @@transaction_isolation

设置数据库的隔离级别:

set session transaction isolation level XXX;

首先我们先把两个数据库会话的隔离级别调成read uncommited;

之后我们在终端插入一条数据,然后查询数据,终端插入成功(并未进行commit)
在这里插入图片描述
然后我们查看workbench中的数据
在这里插入图片描述
发现也能显示插入的数据,然而终端并没有执行commit操作,我们将这种情况称为脏读。
接下来我在终端运行rollback操作。
在这里插入图片描述
发现,workbench也发生了变化。
我们将workbench 中的隔离级别改成read commited。
然后重复上面操作。
在这里插入图片描述
在这里插入图片描述
发现没有出现脏读的情况,说明read commited确实解决了脏读问题。

解决不可重复读

在workbech中隔离级别为 read committed 下,我们做如下实验:

在终端中更新一条数据,然后提交。
在这里插入图片描述
然后在workbench中开启事务,查询数据:
在这里插入图片描述
没有发现问题。
然后再在终端中重复上述步骤。
在这里插入图片描述
然后再次在workbench查询数据
在这里插入图片描述
发现workbech中的数据也发生了更新。在一个事务中重复读数据发现出现了不同的结果,说明还是受到了其他事务的影响,这违背了事务的隔离性,我们称这个问题为不可重复读。
解决这个问题我们可以设置workbench中的隔离级别为repeatable read。
设置workbench中的隔离级别为repeatable read之后,我们再次重复上面的实验。
第一次更新
在这里插入图片描述
查看workbech数据中的情况
在这里插入图片描述
第二次更新
在这里插入图片描述
workbench中的情况
在这里插入图片描述
我们发现没有发生变化,repeatable read 解决了不可重复读问题。

解决幻读

现在workbench中隔离级别为 repeatable read。

我们先在workbench中开启事务查看数据
在这里插入图片描述
一共10条数据
然后我们再在终端开启事务,向数据表中添加一条记录并提交。
在这里插入图片描述
此时,查看workbench中的数据
在这里插入图片描述
还是原来的10条数据
但是我们再workbench中执行更新操作,却发现影响了11条数据。
在这里插入图片描述
我们再将workbench中的事务提交,然后再查看数据
在这里插入图片描述
发现新插入的最后一条数据的sage也发生了更改,这就是幻读。
我们将workbench和终端中的隔离级别设为serializable
我们将最新一条的数据删掉,这样原表中还是10条数据。
然后重复上面的步骤
我们先在workbench中开启事务,查询数据,然后在终端插入一条数据。
在这里插入图片描述
终端在执行insert当中卡住了,之后又报错了。
原来serializable在同一时间仅允许一个事务执行,别的事务会被锁住,当此事务提交之后别的事务才会被执行。
一般在工作中,会将隔离级别设为repeatable read,因为serializable效率低下。

java 执行mysql事务操作的基本格式

ABCD 一个事务Connection conn = nulltry{
// 1. 获得连接 conn = ...; // 2.开启事务 conn.setAutoCommit(false); A B C D //3.提交事务 conn.commit();}catch(){
//4.回滚事务 conn.rollback();}

java 执行mysql事务操作的基本格式----savepoint

AB(必须),CD(可选)Connection conn = null;//保存点,记录当前操作位置,之后可以回滚到指定位置(可以回滚一部分)Savepoint savepoint = null;try{
// 1. 获得连接 conn = ...; // 2.开启事务 conn.setAutoCommit(false); A B savepoint = conn.setSavepoint(); C D //3.提交事务 conn.commit(); }catch(){
if(savepoint!=null) //CD异常 {
conn.rollback(savepoint); // 回滚到CD之前 conn.commit(); // 提交AB } else {
conn.rollback(); // 回滚AB }}

转载地址:http://odaen.baihongyu.com/

你可能感兴趣的文章
error C2664: “CreateFileW”: 不能将参数 1 从“char *”转换为“LPCWSTR”
查看>>
调试串口通用程序的几种技巧
查看>>
GUI 编辑框中读写矩阵
查看>>
matlab成段注释
查看>>
matlab数据的导入和导出,以matlab工作区workspace为source和destination
查看>>
获取字节数
查看>>
福听阅读器 背景色设置
查看>>
保护眼睛 电脑设置
查看>>
【云端3.4 Beta】云端无法启动,从服务器返回了一个参照
查看>>
解决chrome下用google搜索图片第二页以后不显示的问题
查看>>
将163邮箱的通讯录导入到outlook2010
查看>>
winRar过期了,总弹出 “购买……”
查看>>
看过的动漫
查看>>
华硕 P5KPL-AM 前面板耳机没有声音
查看>>
个人常用的Chrome浏览器扩展程序
查看>>
labview 局部变量问题
查看>>
labview 循环外部与数组相连时问题
查看>>
哈佛大学凌晨4点半的景象--哈佛图书馆的二十条训言
查看>>
闲话机器人领域的国际会议
查看>>
Outlook2010到处通讯录
查看>>