1、事务的定义
事务是指一组原子性sql查询操作。
这里强调了原子性,因为在一段时间内人们认为原子是不可分割的最小单位。
原子性就是不可分割的意思。
也就是说这一组sql操作是不可分割的。要么全部执行,要么全部不执行。
2、事务的特性
ACID(原子性,一致性,隔离性和持久性)
一致性:
在转账过程中,中途遇到意外,当导致交易失败。两者之间的钱还是一致的。
转200失败的话,钱还是会回到出账人手里。
转账成功的话,入账人的钱和出账人的钱总和一致。
隔离性:
一般来说,一个事务在提交之前对其他事务是不可见的。
这里是一般来说后面会详细谈到事务的隔离级别;
持久性:
事务一旦提交,所作的修改便会永久保存到数据库中。即使系统崩溃,所做修改的数据也不会丢失。(这块我感觉还是要很多的保护措施的,数据备份之类的一定要做好)
2、隔离的级别
隔离性是个复杂的话题,SQL标准中定义了四个隔离级别。
规定了事务之间所作的修改是否可见,有的定义了事务内和事务间是可见,有的则不可见。通常较低级别的隔离可以执行更高的并发,而且系统的开销也更低。
以下是隔离级别由低到高的排序:
未提交读(read uncommitted)
事务中的修改即使没有提交,对其他事务也是可见的。
个人思考:
这会造成一个问题,就是你修改的事务还没有提交上去,你就过早的拿到了这个值,事务一旦失败,取消当前操作,那么你拿的是完全错误的数据。
产生的问题:
读取未提交的数据称为脏读。
下面是我以前做过的一个演示,你会发现在本事务内即使没有提交也会查看到插入的数据。因为我全在一个控制台里面做的应该算是在一个事务里,然后若该事务对其他事务具有可见性的话,那么一旦回滚。以前查询的数据便是脏数据。
show variables like 'autocommit'\G;
set autocommit=off;
commit;
insert into student values(3,3,'cc',55,66,77,88,99,44,33,22,11);
select classnum,name,seatnum from student;
rollback;
select classnum,name,seatnum from student;
:
提交读(read committed)
这是大多数数据库系统默认的事务级别,但mysql不是。
提交读进行了限制,事务开始时只能查询到已经提交的事务所作的修改。
那么,在提交之前所作的修改对其他事务便是不可见的。那么再次查询到的数据便和上一次不一样。
产生的问题:
两次查询到不一样的结果称为不可重复读。
可重复读(repeatable read)
可重复读是mysql的默认事务级别;
可重复读解决了脏读和不可重复读的缺点,但也有一定的缺陷便是幻读。
产生的问题:
幻读是指当某个事务A在读取事务B在某个范围类的数据时,事务B还对该范围进行了插入操作。当A对B再进行读取时,发现产生了数据幻行。Innodb采用了多版本并发控制解决了这一问题。
可串行化(serializable)
最高的事务级别,强制事务进行串行处理。
ps:这样没有并发了啊。
它在读取数据时对每一行数据都进行加锁,会造成超时等待和锁争用的问题。
不较少使用,除非对数据的有极高的要求,对时间要求较少