事务、事务的四大特性(ACID)、三大并发问题、四种锁、事务的隔离级别

一、什么是事务?

事务是应用程序中一系列严密的操作,所有操作必须成功完成,否则在每个操作中所作的所有更改都会被撤消。也就是事务具有原子性,一个事务中的一系列的操作要么全部成功,要么一个都不做。

事务的结果有两种:当事务中的所有步骤全部成功执行完成时,事务提交。如果其中一个步骤失败,将发生回滚操作,撤消之前到事务开始时的所有操作。

二、事务的四个特性

事务具有四个特征:原子性( Atomicity )、一致性( Consistency )、隔离性( Isolation )和持续性( Durability )。这四个特性简称为 ACID 特性。

原子性:事务是数据库的逻辑工作单位,事务中包含的各操作要么都做,要么都不做。

一致性:事务的执行结果必须是使数据库从一个一致性状态变到另一个一致性状态。因此当数据库只包含成功事务提交的结果时,就说数据库处于一致性状态。如果数据库系统运行中发生故障,有些事务尚未完成就被迫中断,这些未完成事务对数据库所做的修改有一部分已经写入了物理数据库,这时数据库就处于一种不正确的状态,或者说是不一致的状态。

隔离性:一个事务的执行不能受其它事务的干扰。即并发执行的各个事务之间不能互相干扰。

持续性:也称永久性,指一个事务一旦提交,它对数据库中的数据的改变就应该是永久性的。接下来的其它操作或故障不应该对其执行结果有任何影响。

三.三大并发问题

脏数据:它所指的就是未提交的数据。也就是说,一个事务正在对一条记录做修改,在这个事务完成并提交之前,这条数据是处于待定状态的(,这时,第二个事务来读取这条没有提交的数据,并据此做进一步的处理,就会产生对未提交的数据的依赖关系。这种现象被称为脏读。

不可重复读(Non-Repeatable Reads):一个事务先后读取同一条记录,事务在两次读取之间该数据被其它事务所修改,则两次读取的数据不同,称之为不可重复读。

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

四.四种锁

从数据库系统的角度来看,锁分为共享锁和排他锁,从程序员的角度看,锁分为悲观锁和乐观锁。

(1)共享锁(S锁, 读锁)

共享锁锁定的资源可以被其它用户读取,但其它用户不能修改它。在SELECT 命令执行时,SQL Server 通常会对对象进行共享锁锁定。通常加共享锁的数据页被读取完毕后,共享锁就会立即被释放。

(2)排他锁(X锁,写锁)

排他锁锁定的资源只允许进行锁定操作的程序使用,其它任何对该资源的操作均不会被接受。执行数据更新命令,即INSERT、UPDATE 或DELETE 命令时,SQL Server 会自动使用排他锁。但当对象上有其它锁存在时,无法对其加排他锁。排他锁一直到事务结束才能被释放。共享锁可以一层套一层的上锁,但排他锁只能加一个。

(3)乐观锁

总是认为不会产生并发问题,每次去取数据的时候总认为不会有其他线程对数据进行修改,因此不会上锁,但是在更新时会判断其他线程在这之前有没有对数据进行修改,一般会使用版本号机制或CAS操作实现。

version方式:一般是在数据表中加上一个数据版本号version字段,表示数据被修改的次数,当数据被修改时,version值会加一。当线程A要更新数据值时,在读取数据的同时也会读取version值,在提交更新时,若刚才读取到的version值为当前数据库中的version值相等时才更新,否则重试更新操作,直到更新成功。

(4)悲观锁

总是假设最坏的情况,每次取数据时都认为其他线程会修改该数据,所以都会加锁(读锁、写锁、行锁等),当其他线程想要访问数据时,都要阻塞挂起。可以依靠数据库实现,如行锁、读锁和写锁等,都是在操作之前加锁,在Java中,synchronized的思想也是悲观锁。根据范围,锁还可以划分成行级锁和表锁。

五、MySQL的四种隔离级别

(1)Read uncommitted:读未提交,顾名思义,就是一个事务可以读取另一个未提交事务的数据。

事例:老板要给程序员发工资,程序员的工资是3.6万/月。但是发工资时老板不小心按错了数字,按成3.9万/月,该钱已经打到了程序员的户口,但是事务还没有提交,就在这时,刚好程序员去查看自己这个月的工资,发现比往常多了3千元,以为涨工资了非常高兴。但是老板及时发现了不对,马上回滚差点就提交了的事务,将数字改成3.6万再提交。

分析:实际程序员这个月的工资还是3.6万,但是程序员看到的是3.9万。他看到的是老板还没提交事务时的数据。这就是脏读。

那怎么解决脏读呢?Read committed!读提交,能解决脏读问题。

(2)Read committed:读提交,顾名思义,就是一个事务要等另一个事务提交后才能读取数据。

事例:程序员拿着信用卡去享受生活(卡里当然是只有3.6万),当他买单时(程序员事务开启),收费系统事先检测到他的卡里有3.6万,就在这个时候!!程序员的妻子要把钱全部转出充当家用,并提交该事物。当收费系统准备扣款时,再检测卡里的金额,发现已经没钱了(第二次检测卡里的金额当然要等待妻子转出金额事务提交完,才能检测)。程序员就会很郁闷,明明卡里是有钱的…

分析:这就是读提交,若有事务对数据进行更新(UPDATE)操作时,读操作事务要等待这个更新操作事务提交后才能读取数据,可以解决脏读问题。

但在这个事例中,出现了一个事务范围内两个相同的查询却返回了不同数据,这就是不可重复读。

那怎么解决不可重复读问题?Repeatable read !,重复读。

(3)Repeatable read:重复读,就是在开始读取数据(事务开启)时,不再允许修改操作发生。

事例:程序员拿着信用卡去享受生活(卡里当然是只有3.6万),当他买单时(事务开启,不允许其他事务的UPDATE修改操作),收费系统事先检测到他的卡里有3.6万。这个时候他的妻子不能转出金额了。接下来收费系统就可以扣款了。

分析:重复读可以解决不可重复读问题。写到这里,应该明白的一点就是,不可重复读对应的是修改,即UPDATE操作。但是可能还会有幻读问题。因为幻读问题对应的是插入INSERT操作,而不是UPDATE操作。

什么时候会出现幻读?

事例:程序员某一天去消费,花了2千元,然后他的妻子去查看他今天的消费记录(妻子事务开启),看到确实是花了2千元,就在这个时候(时间间隙),程序员又花了1万买了一部电脑,即新增INSERT了一条消费记录,并提交。当妻子打印程序员的消费记录清单时(妻子事务提交),发现花了1.2万元,似乎出现了幻觉,这就是幻读。

那怎么解决幻读问题?Serializable!

(4)Serializable 序列化:Serializable 是最高的事务隔离级别,在该级别下,事务串行化顺序执行,可以避免脏读、不可重复读与幻读。但是这种事务隔离级别效率低下,比较耗数据库性能,一般不使用。


事务的隔离级别


脏读


不可重复读


幻读


Read uncommitted(读未提交)





Read committed(读提交)


×




Repeatable read(重复读)


×


×



Serializable(序列化)


×


×


×

六.总结

大多数数据库默认的事务隔离级别是Read committed(读提交),比如Sql Server , Oracle。

Mysql的默认隔离级别是Repeatable read(重复读)。

隔离级别越高,越能保证数据的完整性和一致性,但是对并发性能的影响也越大。对于多数应用程序,可以优先考虑把数据库系统的隔离级别设为Read Committed(读提交),它能够避免脏读,而且具有较好的并发性能。尽管它会导致不可重复读、幻读和第二类丢失更新这些并发问题,在可能出现这类问题的个别场合,可以由应用程序采用悲观锁或乐观锁来控制。

注意:事务的隔离级别和数据库的并发性是成反比的,隔离级别越高,并发性越低。

原文地址:https://www.cnblogs.com/jimoyu/p/12251282.html

时间: 2024-10-03 16:08:19

事务、事务的四大特性(ACID)、三大并发问题、四种锁、事务的隔离级别的相关文章

数据库事务中的四大特性ACID

一.概念 数据库事务中的四大特性(ACID): A:原子性(Atomicity),一个事务(transaction)中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节. 事务在执行过程中发生错误,会被回滚(rollback)到事务开始前的状态,就像这个事务从未执行过一样. 就像你买东西要么交钱收货一起都执行,要么发不出货,就退钱. C:一致性(Consistency),一致性是指事务使得系统从一个一致的状态转换到另一个一致状态. 比如数据库崩溃后重启,此时数据库处于不一致的状态,

事务概念_四大特性

1.事务概念_四大特性 一.事务 事务的概念:事务是指逻辑上的一组操作,这组操作要么同时完成要么同时不完成. 事务的管理:默认情况下,数据库会自动管理事务,管理的方式是一条语句就独占一个事务. 如果需要自己控制事务也可以通过如下命令开启/提交/回滚事务 start transaction; commit; rollback; JDBC中管理事务: conn.setAutoCommit(false); conn.commit(); conn.rollback(); SavePoint sp = c

数据库事务的四大特性ACID

本篇讲诉数据库中事务的四大特性(ACID),并且将会详细地说明事务的隔离级别. 如果一个数据库声称支持事务的操作,那么该数据库必须要具备以下四个特性: ⑴ 原子性(Atomicity) 原子性是指事务包含的所有操作要么全部成功,要么全部失败回滚,所以事务的操作如果成功就必须要完全应用到数据库,如果操作失败则不能对数据库有任何影响.为了实现原子性,需要通过日志:将所有对数据的更新操作都写入日志,如果一个事务中的一部分操作已经成功,但以后的操作,由于断电/系统崩溃/其它的软硬件错误而无法继续,则通过

事务的四大特性ACID

ACID是指数据库事务的四大特性,是由Jim Gray在19世纪70年代后期提出的概念,1983年Andreas Reuter and Theo Härder创造了ACID这个缩略语用来描述这四大特性. 原子性Atomicity是指事务是一个不可分割的整体,要么处于完成状态,要么处于未完成状态,不存在中间状态. 一致性Consistency是指任何事务操作完成后的结果不允许违背数据一致性的情况,其中包括不允许违背事先定义的约束Constraints等. 隔离性Isolation用于控制数据库的并

数据库事物四大特性-ACID

转载自:http://blog.csdn.net/logogcn/article/details/6828531 事务的:原子性.一致性.分离性.持久性 事物(transaction)是由一些列操作序列构成的执行单元,这些单元要么都做,要么不做,是一个不可分割的工作单元. 数据库事物的四个基本性质(ACID) 1.原子性(Atomicity) 指的是事物中包含的所有操作要么全做,要么全不做(all or none). 2.一致性(consistency) 在事物开始以前,数据库处于一致性的状态,

python事务四大特性ACID

1.原子性 整个事务中的所有操作要么全部提交成功,要么全部失败回滚,对于一个事务来说,不可能只执行其中的一部分操作 2.一致性 一致性就是在没有提交事务前,不管理对数据操作多少次,真实的数据都不会改动,只有提交了事务才会数据更改 3.隔离性 隔离性就是在没有完成本次事务前,不允许其他用户对数据的操作 4.持久性 一旦事务提交了,就永久写到数据库中了 原文地址:https://www.cnblogs.com/zrf-516/p/9021016.html

[转]Java并发的四种风味:Thread、Executor、ForkJoin和Actor

这篇文章讨论了Java应用中并行处理的多种方法.从自己管理Java线程,到各种更好几的解决方法,Executor服务.ForkJoin 框架以及计算中的Actor模型. Java并发编程的4种风格:Threads,Executors,ForkJoin和Actors 我们生活在一个事情并行发生的世界.自然地,我们编写的程序也反映了这个特点,它们可以并发的执行.当然除了Python代码(译者注:链接里面讲述了Python的全局解释器锁,解释了原因),不过你仍然可以使用Jython在JVM上运行你的程

Java并发的四种风味:Thread、Executor、ForkJoin和Actor

这篇文章讨论了Java应用中并行处理的多种方法.从自己管理Java线程,到各种更好几的解决方法,Executor服务.ForkJoin 框架以及计算中的Actor模型. Java并发编程的4种风格:Threads,Executors,ForkJoin和Actors 我们生活在一个事情并行发生的世界.自然地,我们编写的程序也反映了这个特点,它们可以并发的执行.当然除了Python代码(译者注:链接里面讲述了Python的全局解释器锁,解释了原因),不过你仍然可以使用Jython在JVM上运行你的程

事务-----四大特性

事务的第一大特性:原子性(Atomicity)它指一个事务中的所有操作要么都发生,要么都不发生,举个例子,对于银行转账,收款方和发款方必须同时加减同样的money,要么同时加减,要么都不加不减; 事务的第二大特性:一致性(Consistency)指在事务中,所有的数据必须保持完整,对于上述的银行转账,不管怎么转账,总钱数是不会变的; 事务的第三大特性:隔离性(Isolation)指多个用户并发访问数据库时,用户之间的事务不可以互相干扰,而且多个并发事务之间的数据要相互隔离.否则会产生一些问题,如