一、MySQL数据库事务的基本要素
1.原子性
在整个事务中的所有操作就像一个原子,是一个不可分割的单元。在事务中要么全部成功,要么全部失败,不存在一部分成功一部分失败。
2.一致性
在事务前和事务后,数据库的完整性约束没有被破坏。数据库完整性的约束主要是程序员自己定义的。例如:a给b转账,a的账户减少50,b的账户增加50就保证了数据库的完整性,但是如果a的账户减少50但是b的账户没有增加,则破坏了数据库的完整性。
3.隔离性
当一个事务正在处理数据时,另一个事务不能影响这个事务对数据的处理。
4.持久性
当事务提交后无法回滚,将数据存储到数据库中。
二、MySQL事务隔离级别
事务的隔离级别分为读未提交,读已提交,可重复读,可串行化
读未提交 | 事务1可以读到事务2没有提交的数据 |
读已提交 | 事务1只可以读到事务2已经提交的数据 |
可重复读 | 在一个事务中多次读一条数据不会发生改变 |
可串行化 | 事务1没有提交时其他事务无法访问事务1设计到的表 |
由于隔离级别的不同,数据库也会存在一些数据安全性的问题
脏读 | 事务1读到了事务2回滚前的脏数据 |
不可重复读 | 事务1需要多次读同一数据,但是事务1执行途中事务2更改了事务1需要读的数据导致事务1多次读同样的数据结果不同 |
幻读 | 当事务1多次范围查找时,事务2向表中新增数据但是事务1多次范围查找所得结果都不同 |
1.读未提交
事务1修改数据update table set count = count - 50 where id = 1,但是事务1还未提交时,事务2就可以读到这条数据的count值就已经是count - 50了。
这会造成脏读的问题,如果事务1因为报错回滚结果没有提交事务,事务2中读到的数据就是错误的数据,这里我们管这个数据叫做脏数据。
2.读已提交
事务1修改数据update table set count = count - 50 where id = 1,事务1还未提交时,事务2读这条数据的count值还是count,只有在事务1提交事务后,事务2才可以读到这条数据count值为count - 50,这就解决了脏读的问题。
但是这还存在不可重复读的问题。例如事务1查数据select * from table where id = 1,事务1还未提交时,事务2修改数据update table set count = count - 50 where id = 1,这时事务1进行第二次读数据就会导致两次查询查到的数据不同。
3.可重复读
事务1查数据select * from table where id = 1,事务1还未提交时,事务2修改数据update table set count = count - 50 where id = 1,这时事务1进行第二次读数据,这时数据是相同的。这就解决了不可重复读的问题。
但是这还存在幻读的问题。例如事务1进行范围查询select * from table where id < 100,事务1还未提交时,事务2插入新数据insert into table (count) values(100),这是事务1进行第二次范围查找,查到的数据条数不同。
4.串行化
在事务1读写数据时,涉及到的表直接被锁住,其他事务无法对这张表进行读写操作。随便解决了数据安全的问题,但是严重影响了查询效率。