数据库基本知识总结–事务
事务
基本知识
- 原子性(Consistency)
- 事务可以是由多个步骤组成,但是事务整体是不可分割的,在事务执行成功之前,事务中任何步骤操作对于真实数据是没有影响的。并且只要有一个步骤发生错误,整个事务就判定失败,不会提交成功步骤对数据的修改。
- 一致性(Isolation)
- 当事务完成数据提交的时候,必须保证所有数据的完整性,包括结构完整性和内容完整性。
- 隔离性(Transaction Isolation Level)
- 在并发操作下,要保证事务不能对正在被另一个事务修改中的数据进行操作。事务修改数据的前提是要保证该数据的状态必须是修改前或修改后。
- 持久性(Durability)
- 事务完成之后,对系统的影响是永久的。
- 原子性(Consistency)
数据库锁
- 排它锁(Exclusive Locks,即X锁)
- 限制其他事务对该事务操作数据对象的读取和修改。
- 共享锁(Share Locks,即S锁)
- 加了该锁的数据对象可以被其他事务读取,但不能被修改。
- 表级锁
- 表级共享锁限制其他事务对该表的修改,只保留读权限。
- 表级排它锁限制其他事务对该表的任何权限。
- 行级锁
- 锁定行不可被其他事务修改,删除,只可以被select。
- 悲观锁
- 并发进行查询语句加for update的时候,后进行操作的一方不能更新。
- 乐观锁
- 更新语句设置版本号,在指定版本中更新数据。只有相同版本号的语句和数据才能被执行。
- 当一个事务对数据对象添加共享锁之后,其他事务不能对其添加排它锁,但是可以添加共享锁。
- 如果更新多,查询少,用悲观锁,反之用乐观锁。
- 排它锁(Exclusive Locks,即X锁)
读取数据的并发问题
- 脏读:事务 A 读取了事务 B 未提交的数据,并在这个基础上又做了其他操作。
- 不可重复读:事务 A 读取了事务 B 已提交的更改数据。
- 幻读:事务 A 读取了事务 B 已提交的新增数据。
隔离级别
- 未提交读(Read uncommitted)
- 最低隔离等级,在此级别下并发事务之间可以互相读取对方未提交的数据。
- 原理:事务在进行数据读取的时候并没有对所读数据加锁。而在修改数据的时候支队数据增加,行级共享锁,。
- 此级别会导致数据的,脏读,因为一个事务读取的数据可能会是另个一个事务已经修改但未提交的数据。
- 提交读(Read committed)
- 此等级下一个事务修改数据的过程中,如果事务还没提交,其他事务不能读取该数据。但是如果数据还有开始修改,只是刚刚读取数据,其他事务还是可以对数据进行读取。
- 原理:事务对当前被读取的数据对象添加,行级共享锁,读完之后立即释放改锁,然后在修改数据的时候会为数据对象加上,排它锁,直到事务结束才会释放。
- 此级别可以解决数据,脏读,的现象,因为在事务对数据更新的时候,其他事务是无法对数据进行读取的。但是由于读取数据的时候有锁释放的操作,所以在某些情况下会出现事务对同一数据多次读取而出现不一样结果的问题,就也就出现了,不可重复读的读现象,。
- 可重复读(Repeatable reads)
- 此级别下,并发事务只能对被其他事务操作的数据对象进行读操作,无法修改,并且在数据对象被修改的时候不能进行任何操作。
- 原理:事务在数据对象读取的时候添加,行级共享锁,直到事务结束,然后在更新数据对象的时候会对数据对象添加,排它锁,直到事务结束。
- 此级别可以解决,不可重复读,的现象和脏读的现象,因为全程对数据对象添加了,行级共享锁,所以其他事务只有对数据的读权限,保证了事务进行期间读取数据的一致性,在更新的时候会添加,排它锁,所以又解决了,脏读,的现象。
- 可序列化(Serializable)
- 此为最高级别,在事务进行读操作的时候,其他事务只有对该事务操作表的读取权限,当该事务对该表进行修改操作的时候,其他事务对该表没有任何权限。
- 原理:事务进行读取数据的时候,必须先对起加上,表级共享锁,直到事务结束才释放,事务在更新数据的时候,先对其加,表级排它锁,直到事务结束才释放。
- 此级别可以解决,脏读,不可重复读,幻读,的现象。因为在事务对数据读取的时候,其他事务只有对数据的读取权限,以及表的读取权限,在修改数据的时候,没有任何权限。
- 未提交读(Read uncommitted)
- 总结
一般对于数据库读写优化,主要是在并发量与事务隔离等级之间寻找适合当前项目的平衡点,因为隔离等级越高,意味着数据库读写更加准确,但是相应的也会限制同一时间的并发发生。