SQLite数据库----事务的概念(面试必问)和处理

《SQLite数据库—sql语句的基础使用》的开篇,我提到过数据库事务的四大属性:ACID,下面我简单的使用一个例子来介绍一下,什么是数据库的事务。

1.什么是数据库的事务
假设在数据库中有一张表,有用户小明和用户小王,小明账户有1000元,小王账户有1000元,小明向小王账户转账100,正常情况下,转账成功,小明账户减少100(900),小王账户增加100(1100);
但是如果因为网络的原因,导致转账失败,会出现的情况就是,小明提交了转账请求之后,因为网络原因转账失败,小王没有收到,那么就出现小明账户减少100(900),小王账户不变(1000);
为了解决这个问题,就提出了事务;假设出现了网络异常导致转账失败,那么就让数据回滚到上一次commit的状态,也就是刚开始小明提交的时候,这样双方的账户金额都没有变,这就是原子性:要么数据都改变,要么都不变;
同时这也是一致性:数据的状态从一个状态到了另一个状态,小明账户减少100,小王账户加了100,而不是之前的那种小明账户减少100,小王不变;
隔离性下一节再说,还有一个特性就是持久性:当数据事务提交之后,对数据库中的数据的改变时永久性的,无法回滚。
所以针对数据库事务问题,我们在进行DML操作时,尤其是多个操作时,为了防止出现网络原因导致数据修改失败可以回滚的状态,我们在执行sql语句时,默认会自动提交,我们需要设置不要自动提交,而且在关闭数据库连接时,会提交事务,因此我们在执行多个操作时,完成一个操作不要关闭连接,等到最后一次执行完毕之后,再关闭连接。
在实际的应用中,尤其是在批量操作的过程中,要开启事务处理,具体实现如下:
(1)在批量操作开始之前,开启事务
在这里插入图片描述
(2)批量操作完成之后,全部提交到数据库后,关闭事务
在这里插入图片描述
在添加事务操作后,DML所需的时间要少很多,因为在不加事务时,每个DML操作都是默认提交数据到数据库,然后再执行下一次操作;添加事务之后,所有的操作最后一起提交到数据库,这样不仅提高了效率,而且出现其他的问题,可以回滚到最初的状态。

2.事务的隔离性
因为事务的并发可能打来的几个问题,才需要设置隔离级别,防止并发问题;
(1)事务并发带来的问题
**脏读:**两个事务T1,T2,如果T1读取了T2已经更新但是没有提交的数据,之后若T2回滚,那么T1读取的数据就是临时且无效的。
**不可重复读:**两个事务T1,T2,T1读取了一个字段,然后T2更新了该字段,之后T1再次读取该字段,值不一样。
**幻读:**两个事务T1,T2,T1从一个表中读取一个字段,然后T2在该表中插入了几行,之后T1再次读取同一张表,会多出几行
4种隔离级别:
(1)READ UNCOMMITTED(读未提交数据):允许事务读取其他事务没有提交的变更,脏读、不可重复读、幻读都有可能出现;
**(2)READ COMITTED(读已提交的数据):**允许事务读取其他事务的变更,可防止脏读,但是无法避免不可重复读和幻读;
**(3)REPEATEABLE READ(可重复读):**允许事务重复读取同一个字段,每次读到都是同一个值,而且在此期间其他事务不能修改该字段值;
**(4)SERIALIZABLE(串行化):**确保事务从数据表中读取相同的行数据,在此期间,其他事务不能对该数据表增删改;但是所有的并发问题都能避免,但是性能低下。

一般情况下,我们只需要避免脏读即可。

本文主要简单介绍了数据库的事务和隔离操作,本文的理论比较多,在面试中,可能会问到。

发布了15 篇原创文章 · 获赞 5 · 访问量 637

猜你喜欢

转载自blog.csdn.net/qq_33235287/article/details/104125253