什么是数据库事务
数据库事务( transaction)是访问并可能操作各种数据项的一个数据库操作序列,这些操作要么全部执行,要么全部不执行,是一个不可分割的工作单位。事务由事务开始与事务结束之间执行的全部数据库操作组成。
数据库事务的四大特性
数据库事务的四大特性和程序事务相同,即ACID
- A(Atomic)原子性
- C(Consistency)一致性
- I(Islation)隔离性
- D(Durability)持久性
通过一个A给B转账的例子理解一下ACID的概念
关系型数据库中这个事务需要以下操作
- 读A余额,假设是1000
- 对A的余额扣减,假设需要给B转200,则1000-200=800
- 写回A余额,800
- 读B余额,假设也是1000
- 对A的余额增加,则1000+200=1200
- 写回B余额,1200
原子性
1-6的操作要么都执行,要么都回滚
一致性
转账前后AB账户总额不变
隔离性
A给B转帐,只要事务没提交,去查AB的余额都不会变化;A给B转帐不会影响C给B转帐
持久性
一旦转帐成功(事务提交),AB账户的余额将会真正改变
数据库事务的并发问题
事务在并发时可能产生的问题
更新丢失
一个事物的更新覆盖另一个事物的更新
脏读
读取了其他事物未提交的数据
不可重复读
事务读取记录时,其他事务修改了该记录,导致两次读取的数据不同
幻读
事务做范围查询时,其他事物新增了满足范围查询条件的记录,导致范围查询结果条数不一致
数据库事务的隔离级别
MySQL中事物的隔离级别由低到高有以下四个级别:
读未提交(read-uncommitted)(RU)
同一记录:事务写其他事务不能写,可以读取其他事务未提交的数据
读已提交(read-committed)(RC)
同一记录:事务写其他事务不能读写,事务可以读取其他事务已提交的数据
可重复读(repeatable-read)(RR)
同一记录:事务写时其他事务不能读写,事务读时其他事务不能写
串行化(Serializable)(S)
直接将事务串行执行
MySQL默认的隔离级别为RR,Oracle默认为RC
各个隔离级别能解决的问题如下表:
更新丢失 | 脏读 | 不可重复读 | 幻读 | |
---|---|---|---|---|
RU | 解决 | 未解决 | 未解决 | 未解决 |
RC | 解决 | 解决 | 未解决 | 未解决 |
RR | 解决 | 解决 | 解决 | 未解决 |
S | 解决 | 解决 | 解决 | 解决 |