事务特性

事务特性

  • 原子性:事务中的所有操作要么全部执行,要么都不执行;
  • 一致性:一个事务执行之前和执行之后都必须处于一致性状态;假设用户A和用户B两者的钱加起来一共是5000,那么不管A和B之间如何转账,事务结束后两个用户的钱相加起来应该还得是5000,这就是事务的一致性
  • 隔离性:多个事务并发(同时)执行,每个事务都感觉不到系统中有其他的事务在执行;
  • 持久性:一个事务一旦被提交了,那么对数据库中的数据的改变就是永久性的,即便是在数据库系统遇到故障的情况下也不会丢失提交事务的操作;

隔离性

如果没有事务的隔离性,会发生的几种问题:

脏读

脏读是指在一个事务处理过程里读取了另一个未提交的事务中的数据。

  当一个事务正在多次修改某个数据,而在这个事务中这多次的修改都还未提交,这时一个并发的事务来访问该数据,就会造成两个事务得到的数据不一致。例如:用户A向用户B转账100元,对应SQL命令如下

1
2
update account set money=money+100 where name=’B’;
update account set money=money - 100 where name=’A’;

  当只执行第一条SQL时,A通知B查看账户,B发现确实钱已到账(此时即发生了脏读),而之后无论第二条SQL是否执行,只要该事务不提交,则所有操作都将回滚,那么当B以后再次查看账户时就会发现钱其实并没有转。

不可重复读

不可重复读是指在对于数据库中的某个数据,一个事务范围内多次查询却返回了不同的数据值,这是由于在查询之间,被另一个事务修改并提交了。

  例如事务T1在读取某一数据,而事务T2立马修改了这个数据并且提交事务给数据库,事务T1再次读取该数据就得到了不同的结果,发送了不可重复读。

  不可重复读和脏读的区别是:脏读是某一事务读取了另一个事务未提交的脏数据,而不可重复读则是读取了前一事务已提交的数据。

幻读

幻读是指事务T1读取了满足某条件的一个数据集,事务T2插入了一行或者多行数据满足了T1的选择条件,导致事务T1再次使用同样的选择条件读取的时候,得到了比第一次读取更多的数据集

1
2
3
1、T1:select * from users where name = "A";
2、T2:insert into `users`(`id`, `name`) values (1, 'A');
3、T1:select * from users where name = "A";

  幻读和不可重复读都是读取了另一条已经提交的事务,所不同的是不可重复读查询的都是同一个数据项,而幻读针对的是一批数据整体。

隔离级别

MySQL数据库提供了四种隔离级别:

隔离级别脏读不可重复读幻读
未提交读(Read uncommitted)可能可能可能
已提交读(Read committed)不可能可能可能
可重复读(Repeatable read)不可能不可能可能
可串行化(Serializable)不可能不可能不可能

InnoDB默认级别:可重复读(Repeatable read),为什么能避免幻读,另一篇mysql锁有说明(间隙锁)

热评文章