你了解面试官问的事务吗?

一、什么是事务

        事务是应用程序中一系列严密的操作,所有操作必须成功完成,否则在每个操作中所作的所有更改都会被撤消。可以理解为:更新数据库中各种数据项的程序执行单元。就比如:同一根绳上的蚂蚱,要活一起活,要死一起死。

二、事务的四个特性

        事务的四个特性为原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持续性(Durability),简称为ACID

1、原子性:操作要么都发生,要么都不发生。

2、一致性:事务的一致性是指事务的执行不能破坏数据库数据的完整性和一致性,一个事务在执行之前和执行之后,数据库都必须处于一致性状态。事务执行的结果必须是使数据库从一个一致性状态变到另一个一致性状态。

3、隔离性:一个事务的执行不能其它事务干扰。即一个事务内部的操作及使用的数据对其它并发事务是隔离的,并发执行的各个事务之间不能互相干扰。

4、持续性:也称永久性,指一个事务一旦提交,它对数据库中的数据的改变就应该是永久性的。一旦某个事务成功结束,那么它对数据库所做的更新就必须被永久保存下来,接下来的其它操作或故障不应该对其执行结果有任何影响。

三、不考虑隔离性会导致的三个问题

1、脏读:脏读是指在一个事务处理过程里读取了另一个未提交的事务中的数据。当一个事务正在多次修改某个数据,而在这个事务中这多次的修改都还未提交,这时一个并发的事务来访问该数据,就会造成两个事务得到的数据不一致。简单来说就是读取了未提交的数据。

2、不可重复读:一个事务两次读取同一行的数据,结果得到不同状态的结果,中间正好另一个事务更新了该数据,两次结果相异,不可被信任。通俗来讲就是:事务T1在读取某一数据,而事务T2立马修改了这个数据并且提交事务给数据库,事务T1再次读取该数据就得到了不同的结果,发送了不可重复读。简单来说就是两次读取时数据不一样。

3、幻读(虚读):一个事务执行两次查询,第二次结果集包含第一次中没有或某些行已经被删除的数据,造成两次结果不一致,只是另一个事务在这两次查询中间插入或删除了数据造成的。简单来说就是两次读取的数据总数不一样。

四、解决办法(四种隔离级别)

从上往下,隔离强度逐渐增强,性能逐渐变差

隔离级别 脏读 不可重复读 幻读
读未提交 可能 可能 可能
读提交 不可能 可能 可能
可重复读 不可能 不可能 可能
串行化 不可能 不可能 不可能

1、Read Uncommited(读取未提交内容)

读未提交,顾名思义,就是一个事务可以读取另一个未提交事务的数据。但是,读未提交产生了脏读,采用读提交可以解决脏读问题

2、Read Commited(读取提交内容)

读提交,顾名思义,就是一个事务要等另一个事务提交后才能读取数据。读提交,若有事务对数据进行更新(UPDATE)操作时,读操作事务要等待这个更新操作事务提交后才能读取数据,可以解决脏读问题。但在这个事例中,出现了一个事务范围内两个相同的查询却返回了不同数据,这就是不可重复读。但是,读提交两次查询会产生不同的查询结果,就会造成不可重复读问题,采用重复读可以解决此问题。

3、Repeatable Read(重复读)

重复读,就是在开始读取数据(事务开启)时,不再允许修改操作。重复读可以解决不可重复读问题。应该明白的一点就是,不可重复读对应的是修改,即UPDATE操作。但是可能还会有幻读问题。因为幻读问题对应的是插入INSERT操作,而不是UPDATE操作。采用Serializable可以解决幻读问题

4、Serializable(可串行化)

串行化( Serializable)是最严格的事务隔离级別。它要求所有事务都被串行执行,即事务只能一个接一个地进行处理,不能并发执行。可以避免脏读、不可重复读与幻读。但是这种事务隔离级别效率低下,比较耗数据库性能,一般不使用。

命令 作用
SHOW GLOBAL VARIABLES LIKE ‘tx_isolation’; 查看当前全局的事务隔离级别
select @@global.tx_isolation; 使用系统变量查询当前全局事务隔离级别
select @@session.tx_isolation; 使用系统变量查询当前会话的事务隔离级别
set global tx_isolation=‘REPEATABLE-READ’; 设置当前的全局隔离级别
set session tx_isolation=‘REPEATABLE-READ’; 设置当前会话的隔离级别

【注意】

1、大多数数据库默认的事务隔离级别是Read committed,比如Sql Server , Oracle。Mysql的默认隔离级别是Repeatable read。

2、隔离级别的设置只对当前链接有效。对于使用MySQL命令窗口而言,一个窗口就相当于一个链接,当前窗口设置的隔离级别只对当前窗口中的事务有效;对于JDBC操作数据库来说,一个Connection对象相当于一个链接,而对于Connection对象设置的隔离级别只对该Connection对象有效,与其他链接Connection对象无关。

3、设置数据库的隔离级别一定要是在开启事务之前。

おすすめ

転載: blog.csdn.net/weixin_47465999/article/details/119538742