1.MySQl事务的基本要素(ACID)
1.1、原子性(Atomicity):事务开始后所有操作,要么全部完成,要么全部不完成,不可能停滞在中间环节。事务执行过程中出错,会回滚(Rollback)到事务开始前的状态,所有的操作就像没有发生一样。也就是说事务是一个不可分割的整体,就像化学中学过的原子,是物质构成的基本单位
1.2、一致性(Consistency):事务开始前和结束后,数据库的完整性约束没有被破坏 。比如A向B转账,不可能A扣了钱,B却没收到
1.3、隔离性(Isolation):同一时间,只允许一个事务请求同一数据,不同的事务之间彼此没有任何干扰。比如A正在从一张银行卡中取钱,在A取钱的过程结束前,B不能向这张卡转账
1.4、持久性(Durability):事务完成后,该事务所对数据库所作的更改将被保存到数据库之中,不能回滚
2隔离性
在 MySQL 中,事务支持是在引擎层实现的,今天我们就隔离性谈谈,首先我们要知道的一点就是事务隔离的越好效率就越低,所以在实际开发的过程中我们你需要根据需求自己判断采用哪种隔离级别。MySQL事务隔离级别包括读未提交(read uncommitted)、读提交(read-committed)、可重复读(repeatable-read)、串行化(serializable),下面我们举一个例子就实际场景分别谈谈,如下图V1是MySQL中的一个字段的值初始值为test:
2.1读未提交(read uncommitted)
一个事务未提交时,他做的改变就可以被其他的事务看到
这时我们在事务一中查询值为初始值test,事务二中第一次查询为test1(虽然事务一未提交但是事务二中可以看到事务一中未提交的),第二次查询为test1,第三次查询为test1。
2.2读提交(read-committed)
一个事务提交后,它做的改变才能被其他的事务看到
这时我们在事务一中查询值为初始值test,事务二中第一次查询为test(因为此时事务二只能看到事务一中已经提交的),第二次查询为test1,第三次查询为test1。
2.3可重复读(repeatable-read)
一个事务执行过程中看到的数据,总是跟这个事务在启动时看到的数据是一致的
这时我们在事务一中查询值为初始值test,事务二中第一次查询为test,第二次查询为test(可重复读的过程中两次读取的结果相同),第三次查询为test1。
2.4串行化(serializable)
同一行记录,“写”会加“写锁”,“读”会加“读锁”。当出现读写锁冲突的时候后一个访问的事务必须等前一个事务执行完毕
事务二的第一次查询会被所住直到事务一提交。
3.实现
上边讲了数据库的几种隔离级别,那么MySQL时如何达到这种隔离的呢:
串行化:读写的时候加锁
读未提交:直接返回最新值
读提交:在每个sql语句执行时候创建试图,当执行本事务的语句的时候,读取试图的内容,将数据回滚到相应的时刻
可重复读:事务启动的时候创建试图,当执行本事务的语句的时候,读取试图的内容,将数据回滚到相应的时刻
4.回滚日志处理
回滚日志会在最早的事务结束的时候将此事务之前的所有日志删除,所以在MySQL中尽量不要使用长事务,长事务意味着在你的读提交和可重复度中会存在很老的试图,导致回滚日志无法删除占用大量资源。