脏读,不可重复读与幻读

最近面试遇到过数据库中隔离级别的问题。那么隔离级别究竟是什么呢?

隔离级别用于事务,可以解决一些数据库并发问题,如脏读,不可重复读,与幻读(又叫虚读),覆盖更新,丢失更新。

脏读:当你访问查询数据的时候,你看到的数据是别的事务还没提交的数据,数据各种乱七八糟,简直脏的可以。

不可重复读:事务1查询数据之后,事务2更新了同数据,事务1再查的时候,发现数据居然变了。这在同一个事务拥有两次查询处理才会发现的问题,会有隐秘性。比如权限表里面有个权限等级,等级最高的话就只允许管理员访问。现在是8:00定时抢货的时间。事务1会将权限降到最低,让广大客户可以开始抢货。但是数据却出问题了,管理员需要进行维护,需要暂时限制表的访问,这个是事务2。然后阴差阳错的,事务1查询了一下权限,现在是准备开枪的状态,OK,我要更新成可开枪状态了。事务2同一时间进来了,它在事务准备更新为开枪状态前进行了更新,将状态更新成不可开枪。事务1之后马上又更新了状态为可开枪状态。结果,客户们使用着有问题的数据,而管理员看着不停变动的数据正在感叹数据库是不是正在被黑中。。。。这种就是不可重复读的一种特例,叫覆盖更新。

幻读:事务1在多次重复查询过程中查询到事务2提交的新增或者删除的数据。你查询工资,看到你现在的工资,然后去打本子的时候,刚好公司的奖金到了,你一打印出来,发现多了1分钱,你会怀疑自己是不是产生幻觉了。

PS:不可重复读针对更新,而幻读针对插入和删除。

丢失更新:撤销事务时,把之前另一个事务的更新数据覆盖了,导致数据丢失。比如事务1和事务2都更新A字段,事务1更新结束之后,事务2紧接着更新A字段,但是事务2出问题,要回滚。这时候回滚会直接回滚到事务1更新前的状态。

PS:然后说明一下,貌似这个丢失更新在所有的事务隔离级别中都是不会发生的。只是查询资料的时候发现了这个,拿出来说一下而已。如果有同志真的看到过丢失更新的情况的话,请在评论里指出,以免我这里误导了别人。

然后是隔离级别介绍,这是在网上抄下来的:

A.Serializable(串行化):一个事务在执行过程中完全看不到其他事务对数据库所做的更新(事务执行的时候不允许别的事务并发执行。事务串行化执行,事务只能一个接着一个地执行,而不能并发执行。)。

B.Repeatable Read(可重复读):一个事务在执行过程中可以看到其他事务已经提交的新插入的记录,但是不能看到其他其他事务对已有记录的更新。

C.Read Commited(读已提交数据):一个事务在执行过程中可以看到其他事务已经提交的新插入的记录,而且能看到其他事务已经提交的对已有记录的更新。

D.Read Uncommitted(读未提交数据):一个事务在执行过程中可以看到其他事务没有提交的新插入的记录,而且能看到其他事务没有提交的对已有记录的更新。

丢失更新脏读非重复读覆盖更新幻像读
未提交读NYYYY
已提交读NNYYY
可重复读NNNNY
串行化NNNNN

如何设置隔离级别:

可以使用 Transact-SQL 或通过数据库 API 来设置事务隔离级别。

Transact-SQL
Transact-SQL 脚本使用 SET TRANSACTION ISOLATION LEVEL 语句。
ADO
ADO 应用程序将 Connection 对象的 IsolationLevel 属性设置为 adXactReadUncommitted、adXactReadCommitted、adXactRepeatableRead 或 adXactReadSerializable。
ADO.NET
使用 System.Data.SqlClient 托管命名空间的 ADO.NET 应用程序可以调用 SqlConnection.BeginTransaction 方法并将 IsolationLevel 选项设置为 Unspecified、Chaos、ReadUncommitted、ReadCommitted、RepeatableRead、Serializable 或 Snapshot。
OLE DB
开始事务时,使用 OLE DB 的应用程序调用 ITransactionLocal::StartTransaction,其中 isoLevel 设置为 ISOLATIONLEVEL_READUNCOMMITTED、ISOLATIONLEVEL_READCOMMITTED、ISOLATIONLEVEL_REPEATABLEREAD、ISOLATIONLEVEL_SNAPSHOT 或 ISOLATIONLEVEL_SERIALIZABLE。
在自动提交模式下指定事务隔离级别时,OLE DB 应用程序可以将 DBPROPSET_SESSION 属性 DBPROP_SESS_AUTOCOMMITISOLEVELS 设置为 DBPROPVAL_TI_CHAOS、DBPROPVAL_TI_READUNCOMMITTED、DBPROPVAL_TI_BROWSE、DBPROPVAL_TI_CURSORSTABILITY、DBPROPVAL_TI_READCOMMITTED、DBPROPVAL_TI_REPEATABLEREAD、DBPROPVAL_TI_SERIALIZABLE、DBPROPVAL_TI_ISOLATED 或 DBPROPVAL_TI_SNAPSHOT。
ODBC
ODBC 应用程序调用 SQLSetConnectAttr,其中 Attribute 设置为 SQL_ATTR_TXN_ISOLATION,ValuePtr 设置为 SQL_TXN_READ_UNCOMMITTED、SQL_TXN_READ_COMMITTED、SQL_TXN_REPEATABLE_READ 或 SQL_TXN_SERIALIZABLE。
对于快照事务,应用程序调用 SQLSetConnectAttr,其中 Attribute 设置为 SQL_COPT_SS_TXN_ISOLATION,ValuePtr 设置为 SQL_TXN_SS_SNAPSHOT。可以使用 SQL_COPT_SS_TXN_ISOLATION 或 SQL_ATTR_TXN_ISOLATION 检索快照事务。

注意!隔离级别虽然越高对数据越安全,但是却会导致并发效率的下降,严重还会导致死锁。所以隔离级别的设置要小心为上。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值