事务的四大特性
原子性:事务的所有操作在数据库中要么全部正确反映出来,要么完全不反映。
一致性:隔离执行事务时(在没有其他事务并发执行的情况下)保持数据库的一致性。即并发执行的结果要与序列化执行的结果相同。
隔离性:尽管多个事务可能并发执行,但系统保证,对于任何事务 和 ,在 看来, 或者在 开始执行之前已经完成执行,或者在 完成之后开始执行。因此,每个事物都感觉不到系统中有其他事务在并发执行。
持久性:一个事务成功完成后,它对数据库的改变必须是永久的,即使出现系统故障。
事务两大操作
read(X):从数据库把数据项X传送到执行read操作的事务的主存缓冲区的一个也称为X的变量中。
write(X):从执行write的事务的主存缓冲区的变量X中把数据项X传回数据库中。
由于放在主缓冲区中,事务并行执行时会出现问题,下面我们详细讨论。
事务隔离性
事务处理系统允许多个事务并发执行。但多个事务并发更新数据会引起许多数据一致性的复杂问题。
事务串行执行——一次执行一个事务,每个事务仅当前一个事务执行完后才执行。可保证数据一致性,但具有较低的吞吐量和资源利用率。
并发执行的优点
- 提高吞吐量和资源利用率:一个事务由多个步骤组成。一些涉及I/O活动,一些涉及CPU活动。在计算机系统中CPU与磁盘可以并发运作。因此,I/O活动可以与CPU处理并行进行,多个事务可并发执行。当一个事务在一张磁盘上进行读写时,另一个事务可在CPU上运行。增加了系统的吞吐量(给定时间内执行的事务数增加)。同时,CPU与磁盘的利用率也得到提高(如果串行执行,CPU在事务进行磁盘读写时处于空闲状态)。
- 减少等待时间:系统中有长事务和短事务。如果事务串行地执行,短事务可能得等它前面的长事务完成,这可能导致难以预测的延迟。
当多个事务并发地执行时,可能违背隔离性,这导致即使事务都正确地执行,数据库的一致性也可能被破坏。
事务隔离级别
未提交读:允许读取未提交数据。最低一致性级别。
- 脏读。读取了未提交的数据。
已提交读:只允许读取已提交的数据,但不要求可重复读。比如,在事务两次读取一个数据项期间,另一个事务更新了该数据并提交。
- 不可重复读。
可重复读:只允许读取已提交数据,而且在一个事务两次读取一个数据项期间,其他事务不得更新该数据。但事务不要求与其它事务可串行化。
- 幻读。两次读取信息不同。
可串行化:通常保证可串行化调度。
图解
该博文有相关图解:https://blog.csdn.net/starlh35/article/details/76445267
共享锁和排他锁
共享锁(S)
- 如果事务 获得了数据项Q上的共享型锁,则 可读但不能写Q。
排他锁(X)
- 如果事务 获得了数据项Q上的排他型锁,则 既可读又可写Q。
共享型与共享型是相容的,而与排他型不相容。在任何时候,一个具体的数据项上可同时有多个共享型锁。此后的排它锁请求必须必须一直等待该数据项上的所有共享型锁被释放。
排他锁与共享锁不相容,与其它排它锁也不相容。
并发控制
通过锁实现,保护数据一致性。
一级封锁协议:在读取事务之前加共享锁,并在提交该事务后释放。不能避免脏读,不可重复读,幻读,丢失更新。
二级封锁协议:在读取事务前加共享锁,读完释放。在更新数据时加排他锁,提交后释放。防止了脏读,但不能避免不可重复读,幻读,丢失更新。
三级封锁协议:在二级封锁协议的基础上加入:读取之前加共享锁,并在事务执行完提交后释放。避免了脏读和不可重复读,但不能避免幻读和丢失更新。
四级封锁协议:直接对事务中所读取或者更改的数据所在的表加表锁,其他事务不能 读写该表中的任何数据。可避免脏读,不可重复读,幻读,丢失更新。
图解
该博文有相关图解:https://blog.csdn.net/flyingfalcon/article/details/53045672