MySQL-事务

简介

事务适用于保证数据的一致性,由一组相关的insert、delete、update(增删改)语句组成,该组的增删改语句要么全都成功,要么全部失败。

事务和锁

当执行事务操作时(增删改),mysql会在表上加锁,防止其他用户修改表中数据。

mysql数据库控制台事务的几个重要操作

1)start transaction        --开始一个事务

2)savepoint 保存点名         --设置保存点

3)rollback to 保存点名        --回退事务

4)rollback                --回退全部事务

5)commit                --提交事务,所有操作生效,不能回退

#事务操作流程

-- 1.创建测试表
CREATE TABLE t9(
		id INT,
		`name` VARCHAR(32));
		
-- 2.开启事务
START TRANSACTION;

-- 3.设置保存点
SAVEPOINT a;

-- 4.执行dml操作
INSERT INTO t9 VALUES (100, 'tom');
SELECT * FROM t9;

-- 5.设置保存点
SAVEPOINT b;

-- 6.执行dml操作
INSERT INTO t9 VALUES (200, 'lucy');
SELECT * FROM t9;

-- 7.回退到b
ROLLBACK TO b;
SELECT * FROM t9;

-- 8.回退到a
ROLLBACK TO a;
SELECT * FROM t9;

-- 提交事务
COMMIT;

回退事务

保存点(savepoint)是实务中的点,用于取消部分事务,当结束事务(commit)时会自动的删除该事务所定义的所有保存点。当执行回退事务时,通过指定保存点可以回退到指定的点。

提交事务

使用commit语句可以提交事务,当执行了commit语句后,会确认事务的变化、结束事务、删除保存点、释放锁,数据生效。当使用commit语句结束事务后,其他会话【其他链接(例如多个用户连接,一个用户对数据库进行操作后没有提交,另一个用户能看到那些操作的内容,和隔离级别相关)】将可以查看到事务变化后的新数据。

事务细节

1)如果不开始事务,默认情况下增删改操作是自动提交的,不能回滚;

2)如果开始一个事务,没有创建保存点,可以执行rollback语句,默认退回到事务开始的状态;

3)可以在还没有提交的事务中创建多个保存点;

4)可以在事务没有提交前,选择回退到指定的个保存点(回退到更靠前的保存点后,不能再向指定的保存点之后的保存点回退);

5)InnoDB存储引擎支持事务,MyISAM不支持;

6)开始一个事务star transaction或者set autocommmit = off;

-- 事务细节
INSERT INTO t9 VALUES (300,'jack');	-- 执行后自动提交,不能回滚
SELECT * FROM t9;
ROLLBACK;	-- 回滚后没有改变

START TRANSACTION;		-- 回退后到这个位置
INSERT INTO t9 VALUES (400,'lucy');
INSERT INTO t9 VALUES (400,'smith');
SELECT * FROM t9;
ROLLBACK;	-- 回退后,到了事务开始的时候

COMMIT;

-- 开始事务
SET autocommit = off;

MySQL事务隔离级别

在不同的事务中,根据隔离的强度不同,每一个事务看到的表中的数据不同。

1)多个连接开启各自事务,在操作数据库中的数据时,数据库系统要负责隔离操作,以保证各个连接在获取数据时的准确性;

2.如果不考虑隔离性可能会发生如下问题:①脏读;②不可重复读;③幻读;

★脏读(dirty read):当一个事务读取另一个事务尚未提交的修改时,产生脏读(A事务在对表进行数据操作,但是没有commit(提交);而B事务在对表数据进行操作时,操作的数据受到A事务修改的影响,发生脏读);

★不可重复读(nonrepeatable read):同一查询在同一事务中多次进行,由于其他提交事务所做的修改或删除,每次返回不同的结果集,此时发生不可重复读(A事务在对表进行数据操作,操作完成后commit(提交));而B事务在对表数据进行操作时(B事务操作时间长度包括A事务的操作),每次进行同一查询的数据内容不同,受到A事务操作的影响,发生不可重复读);

★幻读(phantom read):同一查询在同一事务中多次进行,由于其他提交事务所做的插入操作,每次返回不同的结果集,此时发生幻读。

MySQL隔离级别定义了事务与事务之间的隔离程度

MySQL隔离级别(4中)脏读不可重复读幻读加锁读
读未提交(Read uncommitted)可能出现可能出现可能出现不加锁
读已提交(Read committed)不可能出现可能出现可能出现不加锁
可重复读(Repeatable read)不可能出现不可能出现不可能出现不加锁
可串行化(Serializable)不可能出现不可能出现不可能出现

加锁

加锁:如果发现一个表正在被A事务操作并且没有commit(提交),那么B事务就不能够再操作这个表(查询数据时会进入等待),当A事务commit(提交)后,B事务才能对表中数据进行操作。

-- 1.开启多个控制台【A控制台进行A事务操作和B控制台进行B事务操作】
-- 2.查看A控制台当前mysql的隔离级别
SELECT @@tx_isolation;
/*
+------------------------------+
| @@tx_isolation          |
+-----------------+
| REPEATABLE-READ |
+------------------------------+
*/

-- 3.把B控制台的隔离级别设置为Read uncommitted
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
SELECT @@tx_isolation;
/*
+--------------------------------+
| @@tx_isolation            |
+------------------+
| READ-UNCOMMITTED |
+--------------------------------+
*/

-- 4.在A控制台创建表
CREATE TABLE `account`(
		id INT,
		`name` VARCHAR(32),
		money INT);

-- 5.A控制台和B控制台先后启动事务
START TRANSACTION;

-- 6.A控制台依次进行添加数据、修改数据、删除数据的操作
-- B控制台多次查询表中数据,在A控制台进行操作的过程中每次查询都不相同
-- B控制台启动的B事务对表进行数据处理时受到A控制台A事务操作的影响;

-- 7.两个控制台提交事务后,依次改变B控制台的隔离级别到read committed、
-- repeatable read、serializable,进行重复实验,B控制台的事务操作逐渐不受
-- A控制台事务操作的影响。
-- 隔离级别read committed的控制台所进行的事务操作会发生不可重复读和幻读;
-- repeatable read 和 serializable不会发生脏读、不可重复读、幻读,前者不加锁,后者加锁

隔离级别设定的相关指令

1)查看当前会话隔离级别

select @@tx_isolation;

2)查看系统当前隔离级别

select @@global.tx_isolation;

3)设置当前会话隔离级别

set session transaction isolation level [read uncommitted [,read committed...]]

-- 隔离级别分为4种:
-- ①读未提交 read uncommitted
-- ②读已提交 read committed
-- ③可重复读 repeatable read
-- ④串行化 serializable

4)设置系统当前隔离级别

set global transaction isolation level [read uncommitted [,read committed...]]

-- 隔离级别分为4种:
-- ①读未提交 read uncommitted
-- ②读已提交 read committed
-- ③可重复读 repeatable read
-- ④串行化 serializable

5)mysql默认的事务隔离级别是repeatable read,一般情况下没有特殊要求,没有必要修改(该级别可以满足大部分项目需求);

6)隔离级别的全局修改,可以修改默认的隔离级别,修改my.ini配置文件,在[mysqld]栏目下编写:transaction-isolation = REPEATABLE-READ

      可选隔离参数有:READ-UNCOMMITTED、READ-COMMITTED、REPEATABLE-READ、SERIALIZABLE。

事务的ACID特性

1)原子性(Atomicity)

原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生;

2)一致性(Consistency)

事务必须使用数据库从一个一致性状态变换到另外一个一致性状态(事务一旦提交之后,会进行一个整体性改变,开启一个新的事务);

3)隔离性(Isolation)

事务的隔离性是多个用户并发访问数据库时,数据库为每一个用户开启的事务,不能被其他事务的操作数据所干扰,多个并发事务之间要相互隔离;

4)持久性(Durability)

持久性是指一个事务一旦被提交,他对数据库中的数据改变是永久性的,接下来即使数据库发生故障也不应该对其有任何影响。

表类型和存储引擎

基本介绍

1)MySQL的表类型由存储引擎(Storage Engines)决定,主要包括MyISAM、innoDB、Memory等。

2)MySQL数据表主要支持六种类型,分别是:

①CSV:CSV存储引擎;

②Memory:基于散列,存储在内存中,对临时表有用;

③ARCHIVE:归档存储引擎;

④MRG_MYISAM:相同MyISAM表的集合;

⑤MYISAM:MyISAM存储引擎;

⑥InnoDB:支持事务、行级锁定和外键

3)这六种又分为两类,一种是“事务安全型”(transaction-safe),比如:InnoDB;其余都属于第二类,称为“非事务安全型”(non-transaction-safe)[myisam 和 memory]。

主要的存储引擎/表类型特点

特点MyISAMInnoDBMemoryArchive
批量插入的速度非常高
事务安全支持
全文索引支持
锁机制表锁行锁表锁行锁
存储限制没有64TB没有
B树索引支持支持支持
哈希索引支持支持
集群索引支持
数据缓存支持支持
索引缓存支持支持支持
数据可压缩支持支持
空间使用N/A非常低
内存使用中等
支持外键支持

1)MyISAM不支持事务、也不支持外键,但其访问速度快,对事务完整性没有要求;

2)InnoDB存储引擎提供了具有提交、回滚和崩溃恢复能力的事务安全。但是比起MyISAM存储引擎,InnoDB写的处理效率差一些并且会占用更多的磁盘空间以保留数据和索引;

3)MEMORY存储引擎使用存在内存中的内容来创建表,每个MEMORY表只实际对应一个磁盘文件。MEMORY类型的表访问非常快,因为它的数据是放在内存中的,并且默认使用HASH索引。但是一旦服务器关闭,表中的数据就会丢失掉,表的结构还在。

#表类型和存储引擎

-- 查看所有的存储引擎
SHOW ENGINES;

-- InnoDB存储引擎
-- 1.支持事务;2.支持外键;3.支持行级锁;

-- myisam存储引擎
CREATE TABLE t16(
		id INT,
		`name` VARCHAR(32)) ENGINE MYISAM;
-- 1. 添加速度快;2.不支持外键;3.支持表级锁。
START TRANSACTION;
SAVEPOINT a;
INSERT INTO t16 VALUES(1,'tom');
SELECT * FROM t16;
ROLLBACK TO a;		-- 回滚操作成功,但是出现警告,数据没有回滚回去(不支持事务)
SELECT * FROM t16;
COMMIT;

-- memory存储引擎
-- 1.数据存储在内存中(关闭MySQL服务,数据丢失,但是表结构还在);
-- 2.执行速度很快(没有IO读写,所以执行速度快);3.默认支持索引(HASH表)。
CREATE TABLE t17(
		id INT,
		`name` VARCHAR(32)) ENGINE MEMORY;
INSERT INTO t17 VALUES(1,'tom'), (2,'jack'),(3,'lucy');
SELECT * FROM t17;
-- 重启mysql后再次查询表,表结构还在数据消失,例如适用于用户状态
DESC t17;
SELECT * FROM t17;

-- 指令修改存储引擎
ALTER TABLE t17 ENGINE = INNODB;

如何选择表的存储引擎

1)如果应用不需要事务,处理的只是基本的CRUD操作,那么就选择MyISAM存储引擎,速度快;

2)如果需要事务,选择InnoDB;

3)Memory存储引擎是将数据存储在内存中,由于没有磁盘IO的等待,速度极快。但由于内存存储引擎,所做的任何修改在服务器重启后消失(例如:用户的在线状态)。

修改存储引擎

ALTER TABLE table_name ENGINE = StorageEngine_name;
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值