5.TCL事务控制语句

TCL事务控制语句

事务属于TCL控制语言(Transaction Control Language )。

一. 事务概述

1.1 什么是事务?为什么要用事务?

​ 一个事务是由一条或者多条sql语句构成,这一条或者多条sql语句要么全部执行成功,要么全部执行失败!

默认情况下,每条单独的sql语句就是一个单独的事务!

举例:

银行转账!张三转10000块到李四的账户,这其实需要两条SQL语句:

给张三的账户减去10000元;

给李四的账户加上10000元。

如果在第一条SQL语句执行成功后,在执行第二条SQL语句之前,程序被中断了(可能是抛出了某个异常,也可能是其他什么原因),那么李四的账户没有加上10000元,而张三却减去了10000元。这肯定是不行的!

你现在可能已经知道什么是事务了吧!事务中的多个操作,要么完全成功,要么完全失败!不可能存在成功一半的情况!也就是说给张三的账户减去10000元如果成功了,那么给李四的账户加上10000元的操作也必须是成功的;否则给张三减去10000元,以及给李四加上10000元都是失败的!

1.2 MySQL中的存储引擎

**1、存储引擎的概念:**在mysql中的数据用各种不同的技术存储在文件(或内存)中。

**2、通过show engines;**来查看mysql支持的存储引擎。

3、 在mysql中用的最多的存储引擎有:innodb, myisam ,memory 等。其中innodb支持事务,而

myisam、memory等不支持事务。

二.事务的分类

1.隐式事务:没有明显的开启和结束标记,比如dml语句的insert、update、delete语句本身就是一条事务

insert into stuinfo values(1,'Jack','男','123@qq.com',12);

2.显式事务:具有明显的开启和结束标记,一般由多条sql语句组成,必须具有明显的开启和结束标记

步骤:
1、开启事务
	取消隐式事务自动开启的功能

2、编写事务需要的sql语句(1条或多条)
	-- insert into stuinfo values(1,'Mark','男','123@qq.com',12);
	-- insert into stuinfo values(2,'Lisa','女','123@qq.com',12);

3、结束事务
	提交事务或回滚事务

三.事务的四大特性(ACID)

原子性(Atomicity):事务中所有操作是不可再分割的原子单位。事务中所有操作要么全部执行成功,要么全部执行失败。

一致性(Consistency):事务执行后,数据库状态与其它业务规则保持一致。如转账业务,无论事务执行成功与否,参与转账的两个账号余额之和应该是不变的。

隔离性(Isolation):隔离性是指在并发操作中,不同事务之间应该隔离开来,使每个并发中的事务不会相互干扰。

持久性(Durability):一旦事务提交成功,事务中所有的数据操作都必须被持久化到数据库中,即使提交事务后,数据库马上崩溃,在数据库重启时,也必须能保证通过某种机制恢复数据。

总结:

-- 原子性(Atomicity):指在事务中包含所有操作,要么都做,要么都不做(不可分割)

-- 一致性(Consistency):数据的改变保证一致

-- 隔离性(Isolation):数据库允许多个并发事务同时对其数据进行读写和修改的能力,防止多个事务并发执行时由于交叉执行而导致数据的不一致。

-- 持久性(Durability):事务处理结束之后,对数据的修改是永久的,即便你的系统出现故障,也不会丢失。(将数据存在了磁盘上)

四.MySql中的事务

​ 在默认情况下,MySQL每执行一条SQL语句,都是一个单独的事务。如果需要在一个事务中包含多条SQL语句,那么需要开启事务和结束事务。

-- 开启事务:start transaction;

-- 结束事务:commit或rollback;

-- 断点  savepoint  断点   rollback to 断点

​ 在执行SQL语句之前,先执行strat transaction,这就开启了一个事务(事务的起点),然后可以去执行多条SQL语句,最后要结束事务,commit表示提交,即事务中的多条SQL语句所做出的影响会持久化到数据库中。或者rollback,表示回滚,即回滚到事务的起点,之前做的所有操作都被撤消了。

由于事务是自动开启的,需要先取消事务的自动开启

-- 查看含有auto的变量
SHOW VARIABLES LIKE '%autocommit%'

-- 取消事务自动开启
SET autocommit = 0;

案例:

创建事务要用到的表

CREATE TABLE account(

	id INT PRIMARY KEY AUTO_INCREMENT,

	NAME VARCHAR(30),

	balance double(10,2)

);

INSERT INTO account(NAME,balance) VALUES('zs', 100000);

INSERT INTO account(NAME,balance) VALUES('ls', 100000);

SELECT * FROM account;

Ø 演示事务执行失败

-- 案例一:回滚 事务执行失败
START TRANSACTION;

UPDATE account SET balance=balance-10000 WHERE id=1;

UPDATE account SET balance=balance+10000 WHERE id=2;

ROLLBACK;
-- 案例二:退出mysql客户端 事务执行失败!
START TRANSACTION;

UPDATE account SET balance=balance-10000 WHERE id=1;

UPDATE account SET balance=balance+10000 WHERE id=2;

Ø 演示事务执行成功

START TRANSACTION;

UPDATE account SET balance=balance-10000 WHERE id=1;

UPDATE account SET balance=balance+10000 WHERE id=2;

COMMIT;

五.事务的隔离级别

5.1 事务并发问题如何发生?

当多个事务同时操作同一个数据库的相同数据时

5.2 事务的并发问题有哪些?

​ 对于同时运行的多个事务, 当这些事务访问数据库中相同的数据时, 如果没有采取必要的隔离机制, 就会导致各种并发问题:

-- 多个事务同时处理,会遇到的现象:
脏读:用户读了修改后未提交的数据(rollback产生)

不可重复读:读取同一条记录,但是两次数据不一样(两次提交同一条记录)

幻读:读取同一张表,两次记录数不一样(两次提交不同的记录)

5.3 如何避免事务的并发问题?

数据库事务的隔离性: 数据库系统必须具有隔离并发运行各个事务的能力, 使它们不会相互影响, 避免各种并发问题。一个事务与其他事务隔离的程度称为隔离级别. 数据库规定了多种事务隔离级别, 不同隔离级别对应不同的干扰程度, 隔离级别越高, 数据一致性就越好, 但并发性越弱。

​ Oracle 支持的 2 种事务隔离级别:READ COMMITED, SERIALIZABLE。 Oracle 默认的事务隔离级别为: READ COMMITED。

​ Mysql 支持 4 种事务隔离级别. Mysql 默认的事务隔离级别为: REPEATABLE READ

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qtZ4Iqgc-1637130161001)(image/1608832313571.png)]

-- 通过设置事务的隔离级别
读未提交READ UNCOMMITTED:允许幻读和不可重复读,脏读

读提交READ COMMITTED:允许幻读和不可重复读,但是不允许脏读
--读提交:本次操作若发生改变了,必须提交,其他人才能看见改变的(Oracle默认)

重复读REPEATABLE READ:允许幻读,但是不允许不可重复读和脏读(MySQL默认)

串行化读SERIALIZABLE:都不允许幻读和不可重复读,脏读
--串行化读:首先重新建立连接,只管自己本次事务操作,不管外部数据的变化(即使提交也看不见)

​ 每启动一个 mysql 程序, 就会获得一个单独的数据库连接. 每 个数据库连接都有一个全局变量@@tx_isolation, 表示当前的事务隔离级别。

-- mysql中默认  第三个隔离级别 repeatable read
-- oracle中默认 第二个隔离级别 read committed

-- 查看当前的隔离级别
select @@tx_isolation;

-- 设置 当前会话 | 数据库系统的全局的 MySQL连接的隔离级别
set session|global transaction isolation level 隔离级别;

读未提交READ UNCOMMITTED:允许幻读和不可重复读,脏读

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-P7ScPRPC-1637130161007)(image/读未提交.png)]

读提交READ COMMITTED:允许幻读和不可重复读,但是不允许脏读

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-I9eQ7Hb1-1637130161037)(image/读提交.png)]

重复读REPEATABLE READ:允许幻读,但是不允许不可重复读和脏读(MySQL默认)

不允许不可重复读和脏读

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vTEBvRUg-1637130161054)(image/重复读.png)]

允许幻读

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VtiYGRiA-1637130161081)(image/重复读-允许幻读.png)]

串行化读SERIALIZABLE:都不允许幻读和不可重复读,脏读

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DdFFSt1G-1637130161089)(image/串行化读.png)]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

what's your name.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值