数据库事务的四大特性以及四种隔离级别
事务的四大特性
首先什么是事务?这是来自官方的解释:数据库事务( transaction)是访问并可能操作各种数据项的一个数据库操作序列,这些操作要么全部执行,要么全部不执行,是一个不可分割的工作单位。
事务由事务开始与事务结束之间执行的全部数据库操作组成,简单的来说就是我们执行一件事情从头到尾的过程。
任何支持事务的数据库,都必须具备四个特性,分别是:原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability),也就是我们常说的事务ACID,
这样才能保证事务中数据的正确性。
原子性:事务中包含的操作被看做一个逻辑单元,这个逻辑单元中的操作要么全部成功,要么全部失败。
一致性:事务完成时,数据必须处于一致状态,数据的完整性约束没有被破坏,事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没 有执行过一样。
隔离性:事务允许多个用户对同一个数据进行并发访问,而不破坏数据的正确性 和完整性。同时,并行事务的修改必须与其他并行事务的修改相互独立。
持久性:事务结束后,事务处理的结果必须能够得到固化。
事务的四种隔离级别
Read uncommitted(读未提交)
顾名思义就是一个事务读取到了另外一个事务没有提交的数据。
例:事务A访问了数据库,它干了一件事情,往数据库里加上了一条新的数据,比如添加一个用户张三,但是没有提交事务。
这时,来了另一个事务B,它要查询所有用户的名字。这时,如果没有事务之间没有有效隔离,那么事务B返回的结果中就会出现“张三”的名字。
按理说不应该出现“张三”这个人,所以“张三”这条数据就为脏数据,这就是“脏读(dirty read)”。
Read committed(读提交)
顾名思义,就是一个事务要等另一个事务提交后才能读取数据。
例:事务A访问了数据库,它要查看“张三”的手机号码,查看的结果为“12345”。这时,事务B来了,因为“张三”修改了手机号码为“66666”,所以要更新一下,然后提交了事务。
接着,事务A还想再看看“张三”的手机号码,于是又执行了查询,结果,两次查出来的手机号码竟然不相同,这就是不可重复读(unrepeatable read)。
Repeatable read(重复读)
重复读,就是在开始读取数据(事务开启)时,不再允许修改操作
事务A访问了数据库,他想要看看数据库的都有哪些用户,于是执行了查询。这时候,事务B来了,往数据库加入了一个新的用户。
这时候,事务A忘了刚才的牛人都有哪些了,于是又执行了。结果,第一次有三个用户,第二次有四个用户。
相信这个时候事务A就蒙了,刚才发生了什么?这种情况就叫“幻读(phantom problem)”。
串行化(Serializable)
这是数据库最高的隔离级别,这种级别下,事务“串行化顺序执行”,也就是一个一个排队执行。
这种级别下,“脏读”、“不可重复读”、“幻读”都可以被避免,但是执行效率奇差,性能开销也最大,所以基本没人会用。
总结一下:
serializable:可避免脏读、不可重复读、虚读情况的发生。
repeatable read:可以避免脏读、不可重复读情况的发生。
read committed:可以避免脏读情况发生。
read uncommitted:最低级别,都会发生。
注意:安全级别越高,性能就越低。选择的时候应该根据实际应用情况选择。