MySQL事务特性与隔离级别

一、事务的特性(ACID)
1、原子性 Atomicity
事务中的全部语句,要么全部成功,要么全部失败,不存在只成功一部分的情况
2、一致性 Consistency
事务的执行不能破坏数据库的完整性和一致性,在事务执行的前后,数据库都是处于一致性的状态。如果数据库运行过程崩溃出现问题,那么就会导致数据的一致性受影响,InnoDB存储引擎通过以下方式保证数据的一致性:
A、双写缓冲区
InnoDB使用doublewrite的技术将数据首先写到双写缓冲区中,然后再将数据写到数据文件中的合适位置,如果写入时出现操作系统崩溃,存储系统崩溃或者mysqld进程宕机,则在重启时进行崩溃恢复

B、崩溃恢复
MySQL在重启的时候,会检测未提交的事务进行崩溃恢复

可以通过以下语句查询双写缓冲区的配置,一般目录配置在于数据文件不同的目录
mysql> show variables like '%write%';
+----------------------------------+----------------------+
| Variable_name | Value |
+----------------------------------+----------------------
| innodb_doublewrite | ON |
| innodb_doublewrite_batch_size | 0 |
| innodb_doublewrite_dir | |
| innodb_doublewrite_files | 2 |
| innodb_doublewrite_pages | 4 |
+----------------------------------+----------------------+
3、隔离性 Isolation
事务的隔离性是指事务之间是相互隔离的,一个事务的执行不能被其他事务干扰。在标准SQL规范中定义了事务的四种隔离级别:
读已提交(READ COMMITTED)
读未提交(READ UNCOMMITTED)
可重复度(REPEATABLE READ)
串行化(SERIALIZABLE)
4、持久性 Durability
一旦事务提交,那么它对数据操作的状态就会永久保存在数据库中,即使发生系统崩溃或者宕机,只要能够重新启动,就能够恢复到原来的状态。通过以下配置选项来控制
innodb_flush_log_at_trx_commit=1
sync_binlog=1
5、事务控制语句
start transaction; // 开始事务
commit; // 提交事务内的操作语句
rollback; // 回滚事务
二、事务的并发问题
1、脏读
事务A读取了事务B更新的数据,然后B回滚操作,那么事务A读取的就是脏数据
2、幻读
假设一张表中有id、name、age、flag四个字段,事务A将age>=19的记录中flag字段改为1。此时另一个事务插入一条age>=19的新纪录,此时事务执行完发现还有一条记录没有改过来,像发生幻觉一样,这就叫做幻读。
3、不可重复读
事务A多次读取同一数据,事务B在事务A读取的过程中,需改并提交了数据,导致事务A多次读取同一数据结果不一致,就称作不可重复读。简单来说就是在一个事务内,多次读取会读到不同的数据
注意:
幻读和不可重复读非常容易混淆,幻读的侧重点在于新增或者删除,不可重复读的侧重点在于修改。解决幻读的现象需要锁表,解决不可重复读需要锁住满足条件的记录。
三、事务的隔离级别
事务隔离级别脏读幻读不可重复读
读已提交(read-committed)
读未提交(read-uncommitted)
可重复度(repeatable-read)
串行化(serializable)
0、设置事务的隔离级别
set session transaction isolation level read uncommitted;
set session transaction isolation level read committed;
set session transaction isolation level repeatable read;
set session transaction isolation level serializable;
1、读已提交(read-committed)
释义:
顾名思义,只能读取到已经提交的数据,没有提交的数据不可被读取到。所以不会出现脏读的现象,但可能出现幻读和不可重复读的情况。
测试:
事务A事务B
start transaction;start transaction;
update t_user set name = ‘Test’ where id = 1update t_user set name = ‘Horace’ where id = 1; // 卡住
commitcommit;
总结:
由于两个事务对同一条记录做修改,所以第二个事务会被锁住,MySQL会锁住这一行数据,直到事务退出或者超时
2、读未提交(read-uncommitted)
释义
事务A可以读取到事务B未提交的数据,如果事务B回滚操作,那么就会出现脏读的现象
测试:
事务A事务B
start transaction;start transaction;
update t_user set name = ‘Test’ where id = 1-
select 下会出现事务A未提交的内容
update t_user set name = ‘xx’ where id = 1; 会锁住
commitcommit;
总结:
读未提交级别下,事务内会读取到其他事务未提交的内容,会出现脏读的情况,一般情况下不允许出现这种情况
3、可重复度(repeatable-read)
释义:
在MySQL数据库里边,这是默认的事务隔离级别,在同一个事务里,同样的select操作得到的结果永远是一样的,因为select的结果是事务开始时的状态。所以存在一种情况是,事务A内读不到事务B提交的内容。
测试:
事务A事务B
begin;begin;
select * from t_user;select * from t_user;
insert into t_user(id, name, age) values(7, ‘Horace-7’, 10)select * from t_user; // 查不到id为7的记录
commit;
insert into t_user(id, name, age) values(7, ‘Horace-7X’, 12’);// 此时报主键冲突
commit;
总结:
事务内读取不到事务外提交的内容,不会出现脏读的现象,但是会出现幻读的现象
4、串行化(serializable)
释义:
串行化是最严格的事务隔离级别,所有的操作都是顺序的,并发级别低,并发量会上不去,InnoDB引擎会隐式加一把共享锁。
测试:
事务A事务B
begin;begin;
insert into t_user(id, name, age)values(9, ‘Horace-9’)select * from t_user; // 会卡住
commitcommit;
总结:
串行化是最严格的隔离级别,所有的操作都是串行化进行的,采用的是悲观的策略。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值