当前位置:首页 > 文章列表 > 数据库 > MySQL > 事务

事务

来源:SegmentFault 2023-02-16 15:20:51 0浏览 收藏

有志者,事竟成!如果你在学习数据库,那么本文《事务》,就很适合你!文章讲解的知识点主要包括MySQL、数据库,若是你对本文感兴趣,或者是想搞懂其中某个知识点,就请你继续往下看吧~

概述

通常的观念认为,事务仅与数据库相关。
将一堆的SQL语句绑定在一起执行,结果是要么全都执行成功(都成功才算成功),要么全都执行失败(有一个失败就按全失败来处理)!

事务的例子

转账,张三(1000元)给李四(1000元)转账100元
开启事务
张三账户减去100元:
update 账户表 set money=money-100 where name='张三';
--900
李四账户上加100元:
update 账户表 set money=money+100 where name='李四';
--1000
结束事务 提交/回滚

特性

(1)原子性

事务中的所有操作都是一个整体,不能被分割,要么全部执行成功,要么全都执行失败。

(2)一致性

在事务执行前后的业务数据之和,是保持一致的。

举例

转账,张三(1000元)给李四(1000元)转账100元。
开启事务
张三(1000元)-100元=900元
李四(1000元)+100元=1100元
结束事务:提交/回滚
不管事务最后是提交了,还是回滚了,张三和李四的账户金额之和,在转账前,转账后是保持一致的!

(3)隔离性

在事务并发时,多个事务之间是具有隔离性的,在一个事务中看不到另一个事务正在进行的数据状态。

(4)持久性

事务提交后,在事务中对数据的更新会持久的保存到数据库中。
在事务提交之前,事务中执行的操作,并没有真正的更新到数据库。

举例

开始事务
张三(1000元)给李四(1000元)转账500元
张三(1000元)-500元=500元
李四(1000元)-500元=1500元
结束事务:提交/回滚
在事务提交执行,张三减去500元,以及李四加上500元,其实并没有真正修改张三和李四的账户金额,只是在日志中记录了,将来如果事务提交了,在事务提交后,才会真正的刀数据库中,更新张三账户金额为500元,更新李四账户金额为1500元!

MySQL中的事务

1.默认情况下,MySQL中的每一条SQL都是一个事务!
2.每次在执行SQL语句之前,会默认开启事务,在执行这条SQL语句之后,会自动提交事务。
3.如果需要让两条或者两条以上的SQL语句在一个事务中执行,需要再执行之前开启事务,在最后一条SQL语句执行完成后,立即结束事务。
开启事务:start transaction;
结束事务:commit(提交)/rollback(回滚);
如果事务汇总的所有SQL语句都执行成功了,最后我们可以提交事务;
如果事务中的SQL语句有一条执行失败,就按全部失败来处理,最后我们会回滚(撤销)事务;

示例

演示A账户给B账户转账
(1)开启事务
start transaction
(2)A账户减去100元
update acc set money=money-100 where name='A'; -- 900元
(3)B账户加上100元
upadate acc set money+100 where name='B'; -- 1100元
(4)查询A,B的账户金额(在不同的cmd窗口进行查看)
select * from acc;
(5)将事务回滚(撤销),将事务提交
rollback;/commit;

并发读问题

多个事务对相同数据进行操作,这叫做事务并发。
在事务并发时,如果没有采取必要的隔离措施,可能会导致各种并发问题,破坏数据的完整性等。这些问题中,其中三类是读问题,分别是:脏读,不可重复读,幻读。

(1)脏读

在一个事务中,读取到另外一个事务为提交更新的数据,称之为脏读。
举例
A(买家)B(卖家)
A转账给B 100元
开启事务:
A-100=900元
B+100=1100元
此时没有提交事务。。。
B在另外一个事务中查询到账户增加了100元,也就是1100元。由于MySQL默认不允许出现脏读,所以要想演示脏读现象,必须将mysql的事务隔离级别设置为最低。
set tx_isolation = 'read-uncommitted';

(2)不可重复读

在一个事务中对同一数据的两次查询结果不一致,是因为另一个事务对该数据进行了修改操作!
举例
事务一:在事务中查询A账户的余额
第一次查询:select * from acc where name='A'; -- 1000
第二次查询:select * from acc where name='A'; -- 900
事务二:A给B转账100元
update acc set money = money-100 where name 'A'
...
提交事务

(3)幻读

在一个事务中对同一张表的两次查询结果不一致,是因为有另一个事务对表进行了插入或者删除操作!
举例
事务一:
第一次:select * from acc where id=3;不存在
插入一条id为3的记录:insert into acc value(2,'C',2000);--插入失败
第二次:select * from acc where id=3;--已存在
事务二:
插入了一条id为3的记录:insert into acc value(3,'C',3000);
提交了事务

隔离级别

read uncommitted(读未提交数据)
安全性最差,不能防止任何的并发读问题,但性能最高,不推荐使用。
red committed(读已提交数据)
Oracle默认的隔离级别
安全性比'读未提交'好,可以防止脏读,但不能防止不可重复读,也不能防止幻读,性能比'读未提交'差。
repeatable read(可重复读)
MySQL默认的隔离级别
安全性比'读已提交'好,可以防止脏读,不可重复读,但不能防止幻读,性能比'读已提交'差。
由于mysql默认的隔离级别不允许出现脏读和不可重复读,因此要想要在mysql中演示这两个现象,必须要设置mysql的隔离级别为最低级别,也就是'读未提交'。
serializable(串行化)
安全性最好,可以防止脏读,不可重复读,幻读,性能最差,也不推荐使用!

设置隔离级别

因为数据库有自己默认的事务隔离级别,我们不需要去设置

mysql中设置事务的隔离级别

查询当前使用的事务隔离级别:
select @@tx_isolation
设置事务的隔离级别:
set tx_isolation='read-uncommitted' 设置隔离级别为'读未提交'
set tx_isolation='read-conmmitted' 设置隔离级别为'读已提交'
set tx_isolation='repeatable-read' 设置隔离级别为'可以重复读'
set tx_isolation='serialiable' 设置隔离级别为'串行化'

JDBC中设置事务的隔离级别

JDBC中通过Connection提供的方法设置事务隔离级别:
Connection.setTransactionIsolation(int level)
level参数可选值如下
Connection.TRANSACTION_READ_UNCOMMITTED 1(读未提交数据)
Connection.TRANSACTION_READ_COMMITTED 2(读已提交数据)
Connection.TRANSACTION_REPEATABLE_READ 4(可重复读)
Connection.TRANSACTION_SERIALIZABLE 8(串行化)
Connection.TRANSACTION_NONE 0(不使用事务)

JDBC执行事务

JDBC也是在执行SQL语句之前,默认开启事务,执行之后,立即提交事务!
因此想要在JDBC中,将两条或者以上的SQL语句放在一个事务中执行,需要关闭自动提交事务!
conn.setAutoCommit(false);

小结

事务就是一组原子操作单元,从数据库的角度说,就是一组SQL指令,要么全都执行成功,若因为某个原因其中一条指令执行有错误,则撤销先前执行过的所有指令。更简答的说就是:要么全部执行成功,要么撤销不执行。

到这里,我们也就讲完了《事务》的内容了。个人认为,基础知识的学习和巩固,是为了更好的将其运用到项目中,欢迎关注golang学习网公众号,带你了解更多关于mysql的知识点!

版本声明
本文转载于:SegmentFault 如有侵犯,请联系study_golang@163.com删除
mysql时区问题mysql时区问题
上一篇
mysql时区问题
30.关于MySQL索引的定义及理解
下一篇
30.关于MySQL索引的定义及理解
查看更多
最新文章
查看更多
课程推荐
  • 前端进阶之JavaScript设计模式
    前端进阶之JavaScript设计模式
    设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
    542次学习
  • GO语言核心编程课程
    GO语言核心编程课程
    本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
    508次学习
  • 简单聊聊mysql8与网络通信
    简单聊聊mysql8与网络通信
    如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
    497次学习
  • JavaScript正则表达式基础与实战
    JavaScript正则表达式基础与实战
    在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
    487次学习
  • 从零制作响应式网站—Grid布局
    从零制作响应式网站—Grid布局
    本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
    484次学习
查看更多
AI推荐
  • 茅茅虫AIGC检测:精准识别AI生成内容,保障学术诚信
    茅茅虫AIGC检测
    茅茅虫AIGC检测,湖南茅茅虫科技有限公司倾力打造,运用NLP技术精准识别AI生成文本,提供论文、专著等学术文本的AIGC检测服务。支持多种格式,生成可视化报告,保障您的学术诚信和内容质量。
    25次使用
  • 赛林匹克平台:科技赛事聚合,赋能AI、算力、量子计算创新
    赛林匹克平台(Challympics)
    探索赛林匹克平台Challympics,一个聚焦人工智能、算力算法、量子计算等前沿技术的赛事聚合平台。连接产学研用,助力科技创新与产业升级。
    50次使用
  • SEO  笔格AIPPT:AI智能PPT制作,免费生成,高效演示
    笔格AIPPT
    SEO 笔格AIPPT是135编辑器推出的AI智能PPT制作平台,依托DeepSeek大模型,实现智能大纲生成、一键PPT生成、AI文字优化、图像生成等功能。免费试用,提升PPT制作效率,适用于商务演示、教育培训等多种场景。
    58次使用
  • 稿定PPT:在线AI演示设计,高效PPT制作工具
    稿定PPT
    告别PPT制作难题!稿定PPT提供海量模板、AI智能生成、在线协作,助您轻松制作专业演示文稿。职场办公、教育学习、企业服务全覆盖,降本增效,释放创意!
    54次使用
  • Suno苏诺中文版:AI音乐创作平台,人人都是音乐家
    Suno苏诺中文版
    探索Suno苏诺中文版,一款颠覆传统音乐创作的AI平台。无需专业技能,轻松创作个性化音乐。智能词曲生成、风格迁移、海量音效,释放您的音乐灵感!
    60次使用
微信登录更方便
  • 密码登录
  • 注册账号
登录即同意 用户协议隐私政策
返回登录
  • 重置密码