事务与锁的相关知识
2018-04-25
ACID,事务的性质
在计算机科学中,ACID (Atomicity, Consistency, Isolation, Durability) 是一组数据库事务的性质,它能够保证数据的正确性和有效性,即使是在程序出现错误、电源发生故障等意外情况下。在数据库中,一系列满足 ACID 的数据库操作可以被视为对数据的单个逻辑操作,我们称之为事务。
- 原子性(Atomicity):一个事务(transaction)中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节。事务在执行过程中发生错误,会被恢复(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。
- 一致性(Consistency):在事务开始之前和事务结束以后,数据库的完整性没有被破坏。这表示写入的资料必须完全符合所有的预设规则,这包含资料的精确度、串联性以及后续数据库可以自发性地完成预定的工作。
- 隔离性(Isolation):数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。
- 持久性(Durability):事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。
其中,事务隔离分为不同级别,设置错误的隔离级别会带来相应的问题。
事务操作常见问题
- 脏读(Dirty reads):当一个事务修改了数据,在未提交或回滚前,另一个事务读取到了这条数据。
- 不可重复读(Non-repeatable reads):在同一事务范围内读取两次相同的数据,所返回的结果不同。比如事务 B 第一次读数据后,事务 A 更新数据并提交,那么事务 B 第二次读取的数据就与第一次不一样。
- 幻读(Phantom reads):在两个事务过程中执行两个相同 Query ,第二个 Query 返回的行集合与第一个 Query 返回的集合不同。
此处,不可重复读与幻读混淆,前者是在执行第二个 Query 前另外的事务修改了符合条件的数据导致的,而后者是在在执行第二个 Query 前另外的事务插入或者删除了数据导致的。比如执行 sum 时其他事务的删除或插入数据会导致结果改变,比如执行插入时其他事务的插入导致了主键的冲突,再比如查询数据时事务的插入或者删除导致了数据变多或者变少,这些都属于幻读带来的问题。
设置合理的事务隔离等级,可以有效的解决以上问题。
为了处理这些问题,事务有四种隔离级别:
事务隔离分为四个级别,包括未提交读(Read uncommitted)、提交读(Read committed)、可重复读(Repeatable read)和串行化(Serializable)。
Isolation Level | Transactions | Dirty Reads | Non-Repeatable Reads | Phantom Reads |
---|---|---|---|---|
TRANSACTION_NONE | Not supported | Not applicable | Not applicable | Not applicable |
TRANSACTION_READ_COMMITTED | Supported | Prevented | Allowed | Allowed |
TRANSACTION_READ_UNCOMMITTED | Supported | Allowed | Allowed | Allowed |
TRANSACTION_REPEATABLE_READ | Supported | Prevented | Prevented | Allowed |
TRANSACTION_SERIALIZABLE | Supported | Prevented | Prevented | Prevented |
隔离级别越高,对性能的影响越大。
JPA中的乐观锁和悲观锁模式
LockModeType | Description |
---|---|
NONE |
No lock. |
OPTIMISTIC |
如果事务T1使用了此模式,以下两种情况不会发生:一、T1修改了某行数据,然后事务T2也修改了这行数据,在T1提交或者回滚数据前,T2提交成功。二、T1读取了某行数据,T2修改或删除了这行数据,并在T1提交前提交成功。 |
OPTIMISTIC_FORCE_INCREMENT |
Optimistic lock, with version update. |
PESSIMISTIC_FORCE_INCREMENT |
Pessimistic write lock, with version update. |
PESSIMISTIC_READ |
如果事务T1使用了此模式,以下两种情况不会发生:一、T1修改了某行数据,然后事务T2在T1提交前读取并获得修改后的数据。二、T1读取了某行数据,T2修改或删除了这行数据,并在T1提交前提交成功。 |
PESSIMISTIC_WRITE |
除了包含PESSIMISTIC_READ 的限制外,使用此模式的事务在提交前会阻止其他事务读取该事务访问的数据。(有待考证) |
READ |
Synonymous with OPTIMISTIC. |
WRITE |
Synonymous with OPTIMISTIC_FORCE_INCREMENT. |
参考
https://www.wikiwand.com/zh-hans/ACID
https://www.wikiwand.com/en/ACID
https://www.cnblogs.com/yldIndex/p/spring_Transactional.html
https://docs.oracle.com/javase/tutorial/jdbc/basics/transactions.html
https://www.wikiwand.com/en/Atomicity_(database_systems)
https://www.wikiwand.com/zh/%E4%BA%8B%E5%8B%99%E9%9A%94%E9%9B%A2
https://docs.oracle.com/javaee/7/tutorial/persistence-locking002.htm