并发冲突
为了提高数据库性能,就不能严格遵守事务隔离性要求,只能允许在一个事务中进行其他事务的操作(并发)。但这样就带来了以下这些问题:
- 丢失的更新:多个事务对同一数据进行更新,后更新会覆盖之前的更新
- 脏读:读到的是“脏”(未提交的)数据。读取了事务提交中的数据,但随后事务回滚,数据被删,
- 不可重复读:两次查询结果不一致。在同一次事务中,针对同一(行)数据,(数据被其他事务发生了修改)
- 幻影读:删除/插入操作失效(有数据被其他事务):第一个事务对一个表中的“全部数据行”进行了修改,同时,第二个事务向表中插入“一行新数据”。那么,第一个事务的用户发现表中还有没有修改的数据行
注意:一个session(query)里的操作不是并发。
隔离级别
查看:DBCC USEROPTIONS
设置:
- SET TRANSACTION ISOLATION LEVEL isolation_level,作用于:connection
- 隔离提示:WITH(isolation_level),作用于:当前语句
未提交读(READ UNCOMMITTED):最低控制级别。事务还没有提交,就可以读。不申请共享锁
提交读(READ COMMITTED):默认级别。已经提交了,才可以读。可避免脏读。共享锁得到结果即释放
可重复读(REPEATABLE READ):除了无法避免幻读,其他并发问题(包括“不可重复读”)都可以避免。共享锁一直到事务结束才释放
串行化(SERIALIZABLE):最高级别。避免一切并发问题。共享锁(还锁定潜在修改:索引和表)直到事务结束才释放
—— 以上通过锁来控制,变化的只有共享锁,排他锁始终是在事务结束后释放。
下面的表格总结了各种隔离级别和各自的缺点
文章转载自:快速开发平台– 云微平台
地址:https://www.hocode.com/