什么是事务?
事务(Transaction)可以理解为是一种机制、一个操作序列,包含了一组数据库操作命令,并且把所有的命令作为一个整体一起向系统提交或撤销操作请求,即发送的一组数据命令要么执行,要么不执行。因此事务是一个不可分割的工作单位,在数据库上执行并发操作时,事务是作为最小的控制单元来使用的,特别适用于多用户同时操作的数据系统。例如:航空公司的订票系统 、银行或证券系统系统等。
事务的四大特性:
2、一致性(Consistency): 事务执行后,数据库状态与其他业务规则保持一致。
如转账业务,无论事务执行成功与否,参与转账的两个账号余额之和应该是不变的。
3、隔离性(lsolation): 隔离性是指在并发操作中,不同事务之间应该隔离开来,使每个并发中的事务不会相互干扰。
例如:多人转账,张三和李四之间的转账与王五和赵六之间的转账,永远是相互独立。
4、持久性(Durability): 一旦事务提交成功,事务中所有的数据库操作都必须被持久化到数据库中 ,即使提交事务后,数据库马上崩溃,在数据库重启后,也必须能保证通过某种机制恢复。
如何执行事务?
在默认情况下,MySQL每执行一条SQL语句,都是一个独立的事务,如果需要在一个事务包含多条SQL语句,那个就需要开启事务和结束事务。
1、开启事务:start transaction;
2、结束事务:commit 或 rollback;
其中 MySQL中默认是开启自动提交模式的,即未指定开启事务时,每条SQL语句都是单独的事务完毕自动提交,可以关闭自动提交模式,手动提交或回滚事务。
使用 SET autocommit=0|1;进行修改。 0表示关闭自动提交, 1表示开启自动提交。
在执行SQL语句之前,先执行strat transaction,这就开启了一个事务(事务的起点),然后可以去执行多条SQL语句,最后要结束事务,commit 表示提交,即事务中的多条SQL语句所做出的影响会持久化到数据库中。或者rollback:表示回滚 ,即回滚到事务的起点,之前的所有操作都会被撤销了!。
下面以张三给李四转账500元的代码示例 来演示 执行事务和结束事务。
账户初始状态图:
开启事务执行转账操作:
但如果先把事务进行提交(commit)在进行回滚 则只能回到提交后的数据。
执行完后效果如下:
事务的3类读问题和四大隔离级别
3大并发读问题:
1、脏读:读到另一事务的未更新数据,即读到了脏数据:
比如说:事务1:张三给李四转账100元。
事务 2:李四查看自己账户。
时间 | 事务1:张三 | 事务2:李四 |
T1 | 开始事务 |
|
T2 | 给李四转账100元 |
|
T3 |
| 开始事务 |
T4 |
| 查看账户余额多了100元(脏读) |
T5 |
| 提交事务 |
T6 | 谁知张三回滚了事务,回到转账之前的状态。 |
2、不可重复读:表示对同一记录的读取不一致,因为另一个对其进行了修改。
比如:事务1:酒店查看两次1008房间状态。
事务2:预订1008房间。
时间 | 事务1 | 事务2 |
T1 | 开始事务 |
|
T2 | 查看酒店1008号房预订状态为空闲 |
|
T3 |
| 开始事务 |
T4 |
| 预订1008号房 |
T5 |
| 提交事务 |
T6 | 再次查看1008号房状态为使用 |
|
T7 | 提交事务 |
3、幻读:表示 对同一个表两次查询不一致,因为另一事务添加一条了记录 与不可重复读很相似 都是不同时间数据不一致,只不过幻读是针对新增数据,而不可重复读是针对更改数据。
四大隔离级别:
4个等级的事务隔离级别,在相同数据环境下,使用相同的输入,执行相同的输入,根据不同的隔离级别,可以导致不同的结果,不同事务隔离级别能够解决的数据并发问题的能力也是不同的。
四大隔离级别区别如下表:
隔离级别 | 读取数据一致性 | 脏读 | 不可重复读 | 幻读 |
可序列化(seralizable) | 最高级别、不会出现并发问题,安全,但性能低。 | 否 | 否 | 否 |
可重复读(Repeatable read) | 事务级:mysql 默认就是可重复读,性能比seralizable好。 | 否 | 否 | 是 |
读已提交数据(Read Committed) | 语句级:oralce 默认的。性能比Repeatable read好 | 否 | 是 | 是 |
读未提交数据(Read uncommitted) | 最低级别:可能出现任何事务并发问题:性能最好。 | 是 | 是 | 是 |