mysql 事务的学习


mysql中的事务, 是比较重要的, 在不少的业务场景中都有用到.

事务的基本介绍

事务是由一个或者多个sql 语句组成的, 在这个单元中, 每个sql 语句都是相互依赖的. 要么一起成功, 要么有一个失败了就集体失败.
其中, 只有默认的 innodb 引擎支持事务.

事务的属性 ACID, 面试会考

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

一致性: 事务必须使数据库从一个一致性状态变换到另外一个一致性状态(A, B 分别有1000 元, A 给B转账后, 两人的总额加起来还是2000 元, 必须一致)

隔离性: 事务的隔离性是指一个事务的执行不能被其他事务干扰, 即一个事务内部的操作及使用的数据对并发的其他事务是隔离的, 并发执行的各个事务之间不能互相干扰.
持久性: 一个事务一旦被提交, 它对数据库中数据的改变就是永久性的, 接下来的其他操作和数据库故障不应该对其有任何影响.( 就是事务提交成功了, 就是不可逆的)

事务的分类

事务两种, 一个是隐式事务, 另一个是显示事务.
只有select, update, deleter, insert 支持事务, alter table 那些修改表和数据库的语句是不支持的.
隐式事务: 事务没有明显的开启和结束的标记, 比如单一条的insert , update, delete 语句
要使用显式事务, 就要先设置自动提交事务的变量为0 , 随后写上开启事务,
事务中的sql 语句, 最后就是结束事务.

事务的使用示范

这里的修改 变量, 把自动提交事务给取消了, 仅仅对当前会话有效

set autocommit = 0 ;
start TRANSACTION ;

UPDATE mp3 set `name` = '夜曲one' where `id`= 1 ;

update mp3 set `name` = '男人海洋one' where `id`= 4;
COMMIT;

回滚是rollback 

查看环境变量的语句 show VARIABLES like ‘autocommit’;

学习过程中遇到的一个版本兼容问题

Mysql的版本差异问题, 5.0没有autocommit 变量但是一样支持事务

事务的语句有语法报错, 那么 这个事务是失败了, 还是 成功了呢?

如果事务中的语句报错了,修改的只会是本地内存的, 仅仅在该会话中看到数据是改了的. 切换一个session , 就会看到并没有提交事务成功.

回滚点的演示

set autocommit=0;
start TRANSACTION ;
UPDATE mp3 set  `name` = 'nightmusic' where id = 1 ;
savepoint  ud ;
delete from mp3 where `name` = '夜曲3' ;
ROLLBACK to ud;

意思就是回滚到指定点的地方

事务并发问题的介绍

对于同时运行的多个事务, 当这些事务访问数据库中相同的数据时, 如果没有采取必要的隔离机制, 就会导致各种并发问题
脏读: 对于两个事务, T1, T2, T1 读取了已经被T2更新但还没有被提交的字段, 之后, 若T2 回滚, T1 读取的内容就是临时且无效的.
不可重读: 对于两个事务, T1, T2 , T1 读取了一个字段,然后T2 更新了该字段, 之后,T1 再次读取同一个字段, 值就不一样了.
幻读: 对于两个事务 T1 T2, T1 从一个表中读取了一个字段, 然后T2 在该表中插入了一些新的行,之后, 如果T1再次读取同一个表, 就会多出几行(T2删除几行也是一样的)
数据库事务的隔离性: 数据库系统必须具有隔离并发运行各个事务的能力, 使它们不会相互影响, 避免各种并发问题.
一个事务与其他事务隔离的程度称为隔离级别. 数据库规定了多种事务隔离级别, 不同隔离级别对应不同的干扰程度, 隔离级别越高, 数据一致性就越好, 但并发越弱.

事务并发问题的具体表象

并发事务处理带来的问题:更新丢失; 脏读;不可重复读;幻读.
更新丢失:就是有多个事务都在对同一行数据进行操作,都先后写入成功.但是会造成先写入的数据被后写入的立即覆盖了. 解决方法是:让上一个用户修改成并提交后, 下一个用户才可以对这个数据进行写入操作.
脏读:事务A读取了事务B 已经修改但是没有提交的数据, 还在这个数据上进行了操作.此时如果别人对事务进行回滚,那么事务A读取的数据无效, 而且它已经对此操作的数据不符合一致性了.
不可重复读: 就是事务A读取到了事务B已经提交的修改数据,不符合隔离性(正常是需要事务A 进行一次commit 之后才能读取到事务B 提交的事务).
幻读:事务A读取了事务B提交的新增数据,不符合隔离性.
幻读和脏读的区别:幻读和脏读的差别: 脏读是读取了另一个事务里修改的数据, 而幻读是读取另一个事务里新增的数据.

mysql 事务的隔离级别

事务的隔离级别有四个, read UNCOMMITTED, read COMMITTED, REPEATABLE read , SERIALIZABLE.
在mysql 中的默认隔离级别是 REPEATABLE read,在Oracle 中的默认隔离级别是 read COMMITTED,就剩下幻读问题没有解决.
查看隔离级别是 select @@tx_isolation;
设置隔离级别, session是当前会话,global全局的
set SESSION TRANSACTION ISOLATION level SERIALIZABLE;

mysql 隔离级别的对比

mysql隔离级别的比较


文章作者: 陌上人如玉
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 陌上人如玉 !
  目录