数据库事务的四大特性(ACID)
- 原子性(Atomiccity):事物中包含的所有操作要么都执行,要么都不执行。
- 一致性(Consistency):事务执行的结果必须是从一个一致性状态变到另一个一致性状态。
例如:某公司在银行中有A和B两个账户,共计有1万元,现在公司想从A账户中转1万元到B账户中,那么就可以定义一个事务,该事物包含两个操作:1.从A账户中减去1万元;2.B账户增加1万元。这两个操作要么全做,要么全不做。全做全不做,A和B两个账户总计仍为1万元,即数据库都处于一致性状态。 - 隔离性(Isolation):一个事务的执行不能被其他事务干扰。
- 持久性(Durability):指一个事务一旦提交,它对数据库中数据的改变就应该是永久的。
如果没有任何并发控制机制,不同的线程执行事务时会出现几类问题:
1. 丢失修改:两个事务T1和T2读入同一数据并修改,T2提交的结果覆盖了T1提交的结果。
2. 脏读:事务T1读取到事务T2修改但未提交的数据,之后事务T2又回滚其更新操作,导致事务T1读到的是脏数据。(事务T1读取到了事务T2未提交的数据)
3. 不可重复读(虚读):事务T1读取某一数据后,事务T2对其做了修改,当事务T1再次读取数据时,得到与前一次不同的数据。
4. 幻读
4.1 事务T1按一定条件从数据库中读取某些数据记录后,事务T2删除了其中部分数据记录,当事务T1再次按相同条件读取数据时,发现某些数据记录不存在了。
4.2 事务T1按一定条件从数据库中读取某些数据记录后,事务T2插入一些记录,当事务T1再次按相同条件读取数据时,发现多了一些记录。
四种隔离级别
为此我们需要通过提供不同类型的“锁”机制针对数据库事务进行不同程度的并发访问控制,由此产生了不同的事务隔离级别:隔离级别(低->高)
-
读未提交(Read Uncommitted)
含义解释:只限制同一数据写事务禁止其他写事务。解决”更新丢失”
名称解释:可读取未提交数据
所需的锁:排他写锁 -
读提交(Read Committed)
含义解释:只限制同一数据写事务禁止其它读写事务。解决”脏读”和”更新丢失”
名称解释:必须提交以后的数据才能被读取
所需的锁:排他写锁、瞬间共享读锁 -
可重复读(Repeatable Read)
含义解释:限制同一数据写事务禁止其他读写事务,读事务禁止其它写事务(允许读)。解决”不可重复读”、”更新丢失”和”脏读”。 注意:没有解决幻读,解决幻读的方法是增加范围锁(range lock)或者表锁。
名称解释:能够重复读取
所需的锁:排他写锁、共享读锁 -
序列化(Serializable)
含义解释:提供严格的事务隔离。它要求事务序列化执行,事务只能一个接着一个地执行,但不能并发执行。如果仅仅通过“行级锁”是无法实现事务序列化的,必须通过其他机制保证新插入的数据不会被刚执行查询操作的事务访问到。
名称解释:限制所有读写事务都必须串行化实行。
下表是各隔离级别对各种异常的控制能力。
常用数据库默认隔离级别
MySQL:可重复读(Repeatable Read)
Oracle:读提交(Read Committed)
SQLServer:读提交(Read Committed)
DB2:读提交(Read Committed)
PostgreSQL:读提交(Read Committed)
如有错误,欢迎指出!