事务的概念

事务 : 指逻辑上的一组操作,组成这组操作的各个单元,要么全部成功,要么全部失败.在不同的环境中,都可以有事务.对应在数据库,就是数据库事务.

事务的使用

(1)开启事务:start transaction;

(2)执行多条SQL语句

(3)回滚或提交:rollback/commit;


事务经典应用场景

比如转账The concept of transaction

账户1 ID 107   余额 10000;

账户2 ID 108    余额 0;

假设 1 给 2 转账 5000;


(1)update account1 set balance = balance - 5000 where ID = 107;

(2)update account2 set balance = balance + 5000 where ID = 108;

假如转账过程中执行完操作(1) 

主机发生故障或者数据库崩溃了

此时账户2的钱未到账

事务的存在就是为了解决上述问题:

本质就是将多个sql语句打包成一个整体,要么全部执行要么一个都不执行(不是真的未执行而是执行一半出现错误后,选择恢复现场,将数据还原到先前的状态 --- 这个恢复数据的操作叫做回滚(rollback));而不会出现执行一半的情况

因为使用了事务,执行sql的开销更大,效率更低;

进行回滚的时候如何知道恢复到什么状态?

此时需要额外的部分记录事务的操作步骤(数据库里有专门记录事务的日志)

事务的四个关键特性

1.原子性(核心特性)

2.一致性(事务执行前后数据是靠谱的)

3.持久性(事务修改后的内容是写到硬盘上的,持续存在的)

4.隔离性(解决并发执行事务引起的问题(修改同一个表的同一数据)

隔离性存在的意义: 就是为了保证数据库在并发处理事务的时候减少问题的出现

并发执行事务可能产生的问题

1.脏读问题

事务A 在对数据进行修改时,事务B 对同一个数据进行读取,(后面可能还会修改)此时事务B 的操作叫做"脏读",读取的数据称为"脏数据";

解决办法:

为了解决脏读问题 Mysql 引入了"写操作加锁"这样的机制(事务A写的时候事务B不能读取,写完才能读取)

写加锁操作:降低了并发程度(降低效率)提高了隔离性(提高数据的准确性)


2.不可重复读

事务A已经提交了一次数据 ,此时事务B开始读数据,在读数据的过程中,事务C又提交了新的数据,此时意味着同一个事务B之内,多次读取数据数据,结果是不同的

(预期一个事务,多次读取的数据是一样的,就叫做不可重复读)

解决方法:

通过"读加锁"(约定事务B开始读的时候,不能修改)

3.幻读

已经约定"读加锁"和"写加锁" 解决了不可重复读和脏读问题

举例说明

假设某一天我(事务A)在敲代码,我的室友(事务B)在后面看,由于"读加锁",室友看的时候,我不能改代码了 --- 干坐着不是办法,那我就再创建一个代码(student.java)写,他看上一个代码(hello.java)        某些情况下,室友再读读到了student.java,表示不能理解;

在读加锁和写加锁前提下,一个事务读取两次数据,数据的值是一样的,当时发现结果集不同,这种叫做"幻读";

解决办法:

数据库使用"串行化"的方法解决幻读问题,彻底放弃并发处理事务,而是一个接着一个串行处理事务;这样操作的并发程度是最低的(效率慢),但隔离性是最高的(准确性也最高)

Mysql 事务及 可能出现的问题_事务



对于上述情况Mysal 提供了四种隔离级别

Mysql 事务及 可能出现的问题_事务_02