MySQL事务

目录

1、什么是事务?

        (1)特点

        (2)限制

2、事务的ACID原则

        (1)原子性

        (2)一致性

        (3)隔离性

        (4)持久性

3、MySQL实现事务的方法

        (1)SET AUTOCOMMIT

        (2)START TRANSACTION

        (3)COMMIT

        (4)ROLLBACK

4、MySQL实现事务的步骤

        * 示例代码

5、事务的原子性、一致性、持久性

6、事务的隔离性 

        (1)什么是事务的隔离性

        (2)用什么方式实现事务的隔离性

7、MySQL中的锁

        (1)基于锁的属性分类

        (2)基于锁的粒度分类

        (3)基于锁的状态分类

8、事务的隔离级别

        (1)事务并发问题

        (2)事务的隔离级别

10、事务的隔离级别解决的问题

(1)READ_UNCOMMITTED(读未提交)

(2)READ_COMMITTED (读提交-不可重复读)

(3) REPEATABLE_READ(可重复读)

 (4)SERIALIZABLE(串行化)

11、事务并发时出现的问题

        (1)脏写( Dirty Write )

        (2)脏读( Dirty Read )

        (3)不可重复读( Non-Repeatable Read )

        (4)幻读( Phantom )

        (5)重复读(REPEATABLE_READ)

12、InnoDB的MVCC


1、什么是事务?

        就好比说是我向你转账了200元,但是密码输错了,我的钱发生了回滚,还是在我的余额里,这就是事务。

        事务(Transaction),就是将一组SQL语句放在同一批次内去执行,如果一个SQL语句出错,则该批次内的所有SQL都将被取消执行。

        (1)特点

        一个事务中如果有一个数据库操作失败,那么整个事务的所有数据库操作都会失败,数据库数据就会回滚到该事务开始之前的状态。

        (2)限制

        MySQL数据库中仅InnoDBBDB类型的数据库表支持事务。

2、事务的ACID原则

        (1)原子性

        意味着数据库中的事务执行是作为原子粒度。即不可再分,整个语句要么执行,要么不执行。

        (2)一致性

        即在事务开始之前和事务结束以后,数据库的完整性约束没有被破坏。

        (3)隔离性

        事务的执行是互不干扰的,一个事务不可能看到其他事务运行时,中间某一时刻的数据。

        (4)持久性

        意味着在事务完成以后 ,该事务所对数据库所作的更改便持久的保存在数据库之中,并不会 被回滚。

3、MySQL实现事务的方法

        (1)SET AUTOCOMMIT

        使用该语句来改变自动提交模式,等于0时关闭自动提交模式, 等于1时开启自动提交模式。默认为1,使用事务时为0。

        (2)START TRANSACTION

        开始一个事务,标记事务的起始点。

        (3)COMMIT

        提交一个事务给数据库。

        (4)ROLLBACK

        将事务回滚,数据回到本次事务的初始状态。

4、MySQL实现事务的步骤

01关闭MySQL自动提交SET AUTOCOMMIT = 0;
02开启一个事务,标记事务的起始点START TRANSACTION;
03向数据库提交事务COMMIT;
03-2将事务回滚,所有的数据库操作被取消ROLLBACK;
04开启MySQL自动提交SET AUTOCOMMIT = 1;
        * 示例代码

        初始化表结果代码

create table bank(
	bid int primary key auto_increment,
	bname varchar(10),
	bmoney decimal(20,2)
);
insert into bank(bname,bmoney) values('杨文琦',5);
insert into bank(bname,bmoney) values('周永康',100000000000000);

select * from bank;

update bank set bmoney = 100000000000000 where bname='周永康';
update bank set bmoney = 5 where bname='杨文琦';

        事务操作代码

 

-- 事务的操作
-- 1. 关闭自动提交
set autocommit = 0;
-- 2. 开始事务
start transaction;
-- 3. 一组sql语句
update bank set bmoney = bmoney-1000 where bname='周永康';
update bank set bmoney = bmoney+1000 where bname='杨文齐';

-- 4. 结束事务(判断)
	-- 提交
	commit;
	-- 回滚
	rollback;
-- 5. 开启自动提交
set autocommit = 1;

         代码结果

         第一次执行因为杨文琦的奇子打错,所以周永康借出去的1000块钱没有到杨文琦手中,执行回滚。

5、事务的原子性、一致性、持久性

        事务的原子性、一致性和持久性由事务的redo日志undo日志来保证。

  • REDO LOG 称为重做日志,提供再写入操作,恢复提交事务修改的页操作,用来保证事务的持久性。
  • UNDO LOG 称为回滚日志,回滚行记录到某个特定版本,用来保证事务的原子性、一致性。

6、事务的隔离性 

        (1)什么是事务的隔离性

        为了让不同的事务之间相互不存在干扰,就需要对事务的操作进行隔离, 事务的隔离性也就是将操作同一个数据的事务相互分离,让操作之间分开有序的执行。

        (2)用什么方式实现事务的隔离性

        通常数据库里都是采用锁的机制,保证事务之间的隔离性。

7、MySQL中的锁

        (1)基于锁的属性分类

        共享锁(读锁、S锁)、排他锁(写锁,X锁)。

        (2)基于锁的粒度分类

        表锁、行锁(记录锁、间隙锁、临键锁)。

        (3)基于锁的状态分类

        意向共享锁、意向排它锁。

8、事务的隔离级别

        (1)事务并发问题

        在事务并发执行的时候,如果不进行事务隔离,那么就会产生脏写、脏读、 重复读、幻读的问题。

        (2)事务的隔离级别
READ_UNCOMMITTED读未提交
READ_COMMITTED读提交(不可重复读)
REPEATABLE_READ可重复读
SERIALIZABLE串行化

         每个隔离级别都针对事务并发问题中的一种或几种进行解决,事务级别越高,解决的并发事务问题也就越多,同时也意味着加的锁就越多,所以性能也会越差

10、事务的隔离级别解决的问题

(1)READ_UNCOMMITTED(读未提交)
事务读取不加锁
事务写入不加锁
解决问题脏写
存在问题脏读、不可重复读、幻读
(2)READ_COMMITTED (读提交-不可重复读)
事务读取加读锁(每次select完成都会释放读锁)
事务写入加写锁
解决问题脏写、脏读
存在问题不可重复读、幻读
(3) REPEATABLE_READ(可重复读)
事务读取加读锁(每次select完不会释放读锁,而是事务结束后才释放)(如果是Mysql的innodb还会有加间隙锁)
事务写入加写锁
解决问题脏写、脏读、不可重复读,幻读(如果是MySQL的inoodb则已解决)
存在问题幻读(如果是Mysql的innodb则不存在)
 (4)SERIALIZABLE(串行化)

        不管读取还是修改所有的事务串行化执行,一个事务的执行必须等待其他事务结束。

11、事务并发时出现的问题

        (1)脏写( Dirty Write )

        对于两个事务 Session A、Session B,如果事务Session A 修改了另一个未提交事务Session B修改过的数据,那就意味着发生了脏写。

        简单来说就是A修改了B已经修改过的但未提交的数据。

        (2)脏读( Dirty Read )

        对于两个事务 Session A、Session B,Session A 读取了已经被 Session B更新但还没有被提 交 的字段。 之后若 Session B 回滚 ,Session A 读取的内容就是临时且无效的。Session A和Session B各开启了一个事务,Session B中的事务先将studentno列为1的记录的name列更新为'张三',然后Session A中的事务再去查询这条studentno为1的记录,如果读到列name的值为'张三',而Session B中的事务稍后进行了回滚,那么Session A中的事务相当于读到了⼀个不存在的数据,这 种现象就称之为脏读 。

        简单来说就是A读取了B已经修改但还未提交的数据,B修改的数据放生回滚,A事务读取到了一个不存在的数据事务。

        (3)不可重复读( Non-Repeatable Read )

        对于两个事务Session A、Session B,Session A 读取了⼀个字段,然后Session B 更新了该字 段。之后 Session A 再次读取 同⼀个字段, 值就不同了。那就意味着发生了不可重复读。我们在Session B中提交了几个隐式事务(注意是隐式事务,意味着语句结束事务就提交了),这些事务都修改了studentno列为1的记录的列name的值,每次事务提交之后,如果Session A中的事务都可以查看到最新的值,这种现象也被称之为不可重复读 。

        简单来说就是A读取完后B来修改了一个字段,A再回来读时不是原来的数据。

        (4)幻读( Phantom )

        对于两个事务Session A、Session B, Session A 从⼀个表中读取了一个字段, 然后 Session B 在该表中插入了一些新的行。之后, 如果 Session A 再次读取同一个表, 就会多出几行。那就意味着发生了幻读。Session A中的事务先根据条件 studentno > 0这个条件查询表student,得到了name列值为'张三'的记录;之后Session B中提交了一个隐式事务 ,该事务向表student中插入了一条新记录;之后Session A 1. 事务并发会出现的问题2 中的事务再根据相同的条件studentno > 0查询表student,得到的结果集中包含Session B中的事务新插入的那条记录,这种现象也被称之为幻读 。我们把新插入的那些记录称之为幻影记录 。

        简单来说就是新增时出现的现象,A读取中B在新增字段,读取过程中看到了B正在增加字段,称之为幻读。

        (5)重复读(REPEATABLE_READ)

        简单来说就是A再读操作时B对字段和数据发生改变,A这边的数据暂时没有发生实时改变,就好比抢演唱会门票在你抢的时候其实已经没有票了,但是你看着还显示的有,这就是重复读。

12、InnoDB的MVCC

        MVCC (Multiversion Concurrency Control),多版本并发控制。顾名思义,MVCC 是通过数据行的多个版本管理来实现数据库的并发控制。这项技术使得在InnoDB的事务隔离级别下执行 一致性读操作有了保证。换言之,就是为了查询一些正在被另一个事务更新的行,并且可以看到它们被更新之前的值,这样在做查询的时候就不用等待另一个事务释放锁。MVCC的实现依赖于:隐藏字段、Undo Log、Read View。

        InnoDB就是通过MVCC机制解决可重复读中的幻读问题。

  • 33
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值