您的位置:首页 > 其它

事务的介绍以及事务隔离级别

2017-03-12 12:14 120 查看

什么是事务

在数据库操作中,一项事务(Transaction) 是由一条或多条操作数据库的SQL语句组成的一个不可分割的工作单元。当事务中的所有操作都正常完成时,整个事务才能被提交到数据库中,如果有一项操作没有完成,则整个事务会被回滚。

其实事务总结起来理解为:逻辑上的一组操作,组成这组操作的各个单元,要么一起成功,要么一起失败。

事务(Transaction)的四个特性及其ACID属性

事务有很严格的定义,需要同时满足四个特性,即原子性、一致性、隔离性、持久性。这四个特性通常称之为ACID特性,具体如下:

原子性(Automicity):事务是一个原子操作单元,其对数据的修改,要么全都执行,要么全都不执行。

一致性(Consistent):在事务开始和完成时,数据都必须保持一致状态。这意味着所有相关的数据规则都必须应用于事务的修改,以保持数据的完整性;事务结束时,所有的内部数据结构(如B树索引或双向链表)也都必须是正确的。

隔离性(Isolation):数据库系统提供一定的隔离机制,保证事务在不受外部并发操作影响“独立”环境执行。这意味着事务处理过程中的中间状态对外部是不可见的,反之亦然。

持久性(Durability):持久性也称永久性(permanence),指一个事务一旦提交,它对数据库中数据的改变就应该是永久性的。系统故障不会对其有任何影响。

并发事务处理带来的问题

相对于串行处理来说,并发处理能力大大增加数据库资源的利用率,提高数据库系统的事务吞吐量,从而可以支持更多的用户。但并发事务处理也会带来一些问题,主要包括以下几种情况。

更新丢失(Lost Update):当两个或多个事务选择同一行,然后基于最初选定的值更新该行时,由于每个事务都不知道其他事务的存在,就会发生丢失更新问题—–最后的更新覆盖了由其他事务所做的更新。例如,两个编辑人员制作了同一文档的电子副本。每个编辑人员独立地更改其副本,然后保存更改后的副本,这样就覆盖了原始文档。最后保存其更改副本的编辑人员覆盖另外一个编辑人员所做的更改。如果在一个编辑人员完成并提交事务之前,另一个编辑人员不能访问同一文件,则可避免此问题。

脏读(Dirty Reads):一个事务正在对一条记录做修改,在这个事务完成并提交前,这条记录的数据就处于不一致状态;这时,另一个事务也来读取同一条记录,如果不加控制,第二个事务读取了这些“脏”数据,并据此做进一步的处理,就会产生未提交的数据依赖关系。这种现象被形象的叫做“脏读”。

不可重复读(Non-Repeatable Reads):一个事务在读取某些数据后的某个时间,再次读取以前读过的数据,却发现其读出的数据已经发生了改变或某些记录已经被删除了!这种现象叫做“不可重复读”。

幻读(Phantom Reads):一个事务按相同的查询条件重新获取以前检索过的数据,却发现其他事务插入了满足其查询条件的新数据,这种现象就称为“幻读”。

如果看上边不能够看懂,可以看这篇博客 脏读,幻读,不可重复读详细介绍

事务的隔离级别

在上面讲到的并发事务处理带来的问题中,“更新丢失”通常是应该·完全避免的。但防止更新丢失,并不能单靠数据库事务控制器来解决,需要应用程序对要更新的数据加必要的锁来解决,因此,防止更新丢失应该是应用的责任。



为了避免事务并发问题的发生,在标准SQL规范中,定义了4个事务隔离级别,不同的隔离级别对事务的处理不同。



隔离级别——————–含义

READ_UNCOMMITTED——————–允许你读取还未提交的改变了的数据。可能导致脏、幻、不可重复读

READ_COMMITTED——————–允许在并发事务已经提交后读取。可防止脏读,但幻读和不可重复读仍可发生

REPEATABLE_READ——————–对相同字段的多次读取是一致的,除非数据被事务本身改变。可防止脏、不可重复读,但幻读仍可能发生

SERIALIZABLE——————–完全服从ACID的隔离级别,确保不发生脏、幻、不可重复读。这在所有的隔离级别中是最慢的,它是典型的通过完全锁定在事务中涉及的数据表来完成的。

事务的隔离级别,是由数据库提供的,并不是所有数据库都支持四种隔离级别

MySQL:READ_UNCOMMITTED、READ_COMMITTED、REPEATABLE_READ、SERIALIZABLE,(默认为REPEATABLE_READ)

Oracle:READ_UNCOMMITTED、READ_COMMITEED、SERIALIZABLE,(默认为READ_COMMITEED)


在使用数据库时候,隔离级别越高,安全性越高,性能越低。

实际开发中,不会选择最高或者最低隔离级别,选择READ_COMMITTED(Oracle默认)、REPEATABLE_READ(MySQL默认)


参考书籍:

《深入浅出MySQL》
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐