面试面试常问之数据库事务
Posted 黑黑白白君
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了面试面试常问之数据库事务相关的知识,希望对你有一定的参考价值。
文章目录
1)什么是事务?
事务(Transaction)是一个最小的不可再分的工作单元,通常一个事务对应一个完整的业务。
- 所谓的事务,它是一个操作序列,这些操作要么都执行,要么都不执行,它是一个不可分割的工作单位。
- 一个完整的业务需要批量的DML(insert、update、delete)语句共同联合完成。
- 事务只和DML语句有关,或者说DML语句才有事务。
- 这个和业务逻辑有关,业务逻辑不同,DML语句的个数不同。
- DML语句相关可参考《【数据库(三)】DML和DDL的学习》。
为什么需要事务?
事务的提出主要是为了解决并发情况下保持数据一致性的问题。
例如,银行转账工作:从一个账号扣款并使另一个账号增款,这两个操作要么都执行,要么都不执行。所以,应该把它们看成一个事务。
- 以下是银行账户表t_act(账号、余额):
actno balance 1 500 2 100 - 进行转账操作:
update t_act set balance=400 where actno=1;
update t_act set balance=200 where actno=2;- 以上两条DML语句必须同时成功或者同时失败:
- 当第一条DML语句执行成功后,并不能将底层数据库中的第一个账户的数据修改,只是将操作记录了一下,这个记录是在内存中完成的;
- 当第二条DML语句执行成功后,和底层数据库文件中的数据完成同步。
- 若第二条DML语句执行失败,则清空所有的历史操作记录,要完成以上的功能必须借助事务。
事务是数据库维护数据一致性的单位,在每个事务结束时,都能保持数据一致性。
事务四大特征(ACID)
- 原子性(Atomic):事务是最小工作单位,不可再分。事务中的操作要么全部成功,要么全部失败。
- 一致性(Consistency):保证数据的状态操作前和操作后保持一致。
- 隔离性(Isolation):多个事务同时操作相同数据库的同一个数据时,一个事务的执行不受另外一个事务的干扰。
- 持久性(Durability):一个事务一旦提交,则数据将持久化到本地,除非其他事务对其进行修改。
1.1 事务的分类
-
隐式事务:
没有明显的开启和结束事务的标志。
- 比如insert、update、delete语句本身就是一个事务。
-
显式事务:
具有明显的开启和结束事务的标志。
1、开启事务 set autocommit=0; //取消自动提交事务的功能 start transaction; 2、编写事务的一组逻辑操作单元(多条sql语句) insert update delete savepoint //断点 3、提交事务或回滚事务 commit; rollback; commit to 断点 rollback to 断点
*关于savepoint
用户在事务(transaction)内可以声明(declare)被称为保存点(savepoint)的标记。保存点将一个大事务划分为较小的片断。
- 用户可以使用保存点(savepoint)在事务(transaction)内的任意位置作标记。
- 之后用户在对事务进行回滚操作(rolling back)时,就可以选择从当前执行位置回滚到事务内的任意一个保存点。
- 例如用户可以在一系列复杂的更新(update)操作之间插入保存点,如果执行过程中一个语句出现错误,用户可以回滚到错误之前的某个保存点,而不必重新提交所有的语句。
1.2 步骤
- 开启事务(任何一条DML语句(insert、update、delete)执行,标志事务的开启)
- 编写事务的一组逻辑操作单元(多条sql语句)
- 提交事务或回滚事务
2)事务的隔离性(Isolation)
为什么需要隔离性?
当多个事务同时操作同一个数据库的相同数据时,可能发生事务并发问题。
2.1 事务的隔离级别
1、读未提交:read uncommitted
这种隔离级别最低,这种级别一般是在理论上存在,数据库隔离级别一般都高于该级别。
- 事务中的修改,即使没有提交,在其他事务也都是可见的。
- 结果:产生脏读。
2、读已提交:read committed
Oracle默认隔离级别。
- 一个事务从开始直到提交之前,所做的任何修改对其他事务都是不可见的。
- 这种级别可以避免“脏数据”。
- 这种隔离级别会导致“不可重复读取”。
- 因为在这多次读之间可能有其他事务更改这个数据,每次读到的数据都是已经提交的。
3、可重复读:repeatable read
MySQL默认级别。
- 事务A在执行查询时,对检索的数据(范围性)都加了行锁(LOCK),这样其他事务就无法对这些加了锁的数据进行更改。
- 可以避免“不可重复读取”,达到可重复读取。
- 虽然可以达到可重复读取,但是会导致“幻读”。
- 因为虽然对检索到的数据加了锁,但是并没有阻止别的事物在这些数据行中间插入新的数据行,导致同一事物多次查询时,突然发现多出来一行或几行数据(幻行)。
4、串行化:serializable
这种隔离级别很少使用,吞吐量太低,用户体验差。
- 事务A和事务B,事务A在操作数据库时,事务B只能排队等待。
- 这种级别可以避免“幻读”,每一次读取的都是数据库中真实存在数据,事务A与事务B串行,而不并发。
- 由于读取的每行数据都加锁,会导致大量的锁征用问题,因此性能也最差。
2.2 查看和设置隔离级别
事务隔离级别的作用范围分为两种:
- 全局级:对所有的会话有效
- 会话级:只对当前的会话有效
查看:
select @@tx_isolation; //查看当前会话隔离级别
select @@global.tx_isolation; //查看系统当前隔离级别
设置:
set session transaction isolation level repeatable read; //设置当前会话隔离级别
set global transaction isolation level repeatable read; //设置系统当前隔离级别
【部分内容参考自】
-mysql——事务(Transaction)详解:https://xulinjie.blog.csdn.net/article/details/79666086
- 数据库系列之——事务隔离的可重复读:https://blog.csdn.net/weixin_42336774/article/details/86274281
以上是关于面试面试常问之数据库事务的主要内容,如果未能解决你的问题,请参考以下文章