数据库事务和并发
1.概述
数据库事务:在对数据库执行操作时,我要执行一长串的操作。但是运行到一半的时候突然断电了,就导致了我的数据一部分写进去了,一部分没有写进去。导致数据出错和数据混乱的问题。比如A向B转账1000块,A的账户应该减1000,B的账户应该加1000,但是前面减少执行成功了,后面增加没有。这显然是不行的。所以数据库事务就是解决这种问题的。
2.ACID特性
- 原子性(Atomicity):事务的操作时一个原子的操作单元。事务的所有操作在执行过程中要么一次全部成功,要么一次全部失败。
- 一致性(Consistency):事务操作不能破坏数据库的完整性和一致性。
- 隔离性(Isolation):事务的并发是相互隔离的,每一个事务都要自己的数据空间,一个事务不能被另一个事务干扰。
- 持久性(Duration):一旦事务执行成功,数据将会永久保存。
3.隔离级别
上述提到事务的隔离性,隔离有四个级别,按照级别的高低如下:
-
读未提交(READ_UNCOMMITTED):最低级别的隔离。一个事务在处理数据后提交了,但是该事务还没有完成,此时允许另一个事务读取该数据。这不能解决脏读问题。
-
读已提交(READ_COMMITTED):只能在事务完成之后读取数据,解决了脏读问题,但是没有解决可重复读问题。
-
可重复读(REPEATABLE_READ):对于多次读取同一个数据,这个数据的值在读取的前后保持一致。结局了可重复读问题,但是解决不了幻读问题。
-
串行化(SERIALIZABLE):最高级别的隔离。不允许数据库并发执行事务,只能串行执行。也就是按照事务的先后顺序执行。
一般数据库的隔离级别是不可重复读
4.并发产生的问题
-
读脏数据:事务只完成一部分但是还没有全部完成,另一个事务就去读取数据。
例如:事务A往账户里存钱,同时事务B往账户里取钱。事务B在取出钱之后事务A存入,但是由于某一原因B撤销了事务。导致最后的钱不一致。
-
不可重复读:一次事务多次读取数据。
例如:事务A读两次账户余额,事务B取出钱。事务A在第一次读取完之后事务B取出钱并提交数据,这个时候事务A又来读取余额,导致两次读取数据不一致。 -
幻读:幻读就是指同样的事务操作,在前后两个时间段内执行对同一个数据项的读取,可能出现不一致的结果。
5.锁
数据库实现并发,当然也少不了锁。
- 共享锁:也称为读锁。事务给数据加上共享锁之后,只允许其它事务读,不允许其他操作。
- 独占锁:也称为写锁。事务给数据加上独占锁之后,其他事务不能访问该数据。