事务
简介
特性
数据库操作存在的不确定情况
隔离级别
简介
事务 是由事务开始与事务结束之间执行的全部数据库操作组成。
特性
1、原子性(Atomicity):事务中的全部操作在数据库中是不可分割的,等同于一个原子操作。要么全部执行,要么全部不执行;
2、一致性(Consistency):几个并行执行的事务,其执行结果必须与按某一顺序串行执行的结果相一致;
3、隔离性(Isolation):事务的执行不受其他事务的干扰,事务执行的中间结果对其他事务必须是透明的;
4、持久性(Durability):对于任意已提交事务,系统必须保证该事务对数据库的改变不被丢失,即使数据库出现故障。
事务的ACID特性是由关系数据库系统(DBMS)来实现的,DBMS采用日志来保
证事务的原子性、一致性和持久性。日志记录了事务对数据库所作的更新,如果
某个事务在执行过程中发生错误,就可以根据日志撤销事务对数据库已做的更新,
使得数据库同滚到执行事务前的初始状态。
1
2
3
4
~~~~~~~ 对于事务的隔离性,DBMS是采用锁机制来实现的。当多个事务同时更新数据库中相同的数据时,只允许持有锁的事务能更新该数据,其他事务必须等待,直到前一个事务释放了锁,其他事务才有机会更新该数据。
数据库操作存在的不确定情况
1.更新丢失
~~~~~~~ 两个事务都同时更新一行数据,一个事务对数据的更新把另一个事务对数据的更新覆盖了。这是因为系统没有执行任何的锁操作,因此并发事务并没有被隔离开来。
2.脏读
~~~~~~~ 一个事务读取到了另一个事务未提交的数据操作结果。这是相当危险的,因为很可能所有的操作都被回滚。
3.不可重复读(Non-repeatable Reads)
~~~~~~~ 一个事务对同一行数据重复读取两次,但是却得到了不同的结果。
(1) 虚读:事务T1读取某一数据后,事务T2对其做了修改,当事务T1再次读该数据时得到与前一次不同的值。
(2) 幻读(Phantom Reads):事务在操作过程中进行两次查询,第二次查询的结果包含了第一次查询中未出现的数据或者缺少了第一次查询中出现的数据(这里并不要求两次查询的SQL语句相同)。这是因为在两次查询过程中有另外一个事务插入数据造成的。
隔离级别
为了避免上面出现的几种情况,在标准SQL规范中,定义了4个事务隔离级别,不同的隔离级别对事务的处理不同。
读未提交(Read Uncommitted)
也就是脏读,但不允许更新丢失。
如果一个事务进行读操作,则其他事务只能同时进行读操作,不能写操作;如果一个事务已经开始写数据,则其他事务不允许同时进行写操作,但可以读操作。该隔离级别可以通过“排他写锁”实现。
读提交(Read Committed)
解决了脏读问题。
这可以通过“共享读锁”(s锁)和“排他写锁”(x锁)实现。读取数据的事务允许其他事务同时读取该行数据,但是未提交的写事务将会禁止其他事务读写该行。
可重复读取(Repeatable Read)
解决了不可重复读和脏读,但是有时可能出现幻读。
这可以通过“共享读锁”和“排他写锁”实现。读取数据的事务将会禁止写事务(但允许读事务),写事务则禁止任何其他事务。
序列化(Serializable)
提供严格的事务隔离。它要求事务序列化执行,事务只能一个接着一个地执行,不能并发执行。仅仅通过“行级锁”是无法实现事务序列化的,必须通过其他机制保证新插入的数据不会被刚执行查询操作的事务访问到。
前三个级别都是行级锁,而序列化需要加表级锁!
隔离级别越高,越能保证数据的完整性和一致性,但是对并发性能的影响也越大。对于多数应用程序,可以优先考虑把数据库系统的隔离级别设为Read Committed。它能够避免脏读取,而且具有较好的并发性能。尽管它会导致不可重复读、幻读和第二类丢失更新这些并发问题,在可能出现这类问题的个别场合,可以由应用程序采用悲观锁或乐观锁来控制。
————————————————
版权声明:本文为CSDN博主「Lb_CsdnJava」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/Lb_CsdnJava/article/details/104361916
郑重声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,多谢。