数据库的事务指的是一组业务处理逻辑,这组逻辑处理要求要么都成功要么都失败(原子性),执行前数据和执行后数据状态总是一致的(一致性),事务之间的处理不会互相影响(隔离性),事务执行完毕之后数据必须持久化了()。一个具体的数据库产品会用一些技术手段来实现事务的这些特性。比如用undo log实现数据回滚,不同的数据库锁策略来实现不同的隔离性。清晰地了解这些特性的实现细节有助于正确地设计和实现复杂的业务逻辑。接下来主要介绍下数据库事务隔离性是怎么实现的。
事务的隔离性本质上是如何控制对数据库数据的并发读写。数据库的并发读写会带来如下几个问题:
- 脏读
- 不可重复读
- 幻读
- 由于事务回滚带来的丢失更新(第一类丢失更新)
- 由于事务写互相覆盖带来的丢失更新(第二类丢失更新)
因此对并发访问的控制实际上转换成解决上面几个并发问题。对于解决不同的并发问题需要不同程度的使用锁,事务隔离性分为
- 读未提交(啥都不管,事务内可能读到其他事务还没commit前的数据)
- 读提交(RC):解决了脏读
- 可重复读(RR):解决了脏读和不可重复读)
- 可串行化(Serializable):解决脏读,不可重复度以及幻读
( 下面介绍的内容以mysql为准)
数据库锁根据锁定互斥行为的不同分为:
- 共享锁(读锁或S锁):若事务T对某一对象加上了共享锁,那么任何事务都可以对数据加共享锁读数据,但是不能加X锁或修改数据
- 排它锁(写锁或X锁):若事务T给对象施加排他锁,只有T事务能够修改数据,其他任何事务不允许加S或X锁,直到T释放A上的锁
根据锁定对象不同主要有:
- 表锁:对整张表进行锁定,一般用在DDL操作时候
- 索引记录锁:对单条数据记录进行锁定
- 间隙锁:对某一数据区间进行锁定
- next-key-lock:记录锁+间隙锁
按照最朴素的做法,要实现RC和RR的隔离效果所有的读数据必须加共享锁,写数据加排他记录锁,而要防止幻读甚至要进行表级锁定,串行化操作,这个效率是无法接受的,因此为了提高并发效率,很多数据库软件都实现了MVCC(多版本并发控制)的方式,基本的实现原理如下:
每条数据记录增加三个隐藏字段,其中有创建版本号,删除版本号,回滚指针
DB系统每次开启一个新事务就会给事务生成一个递增的唯一的事务ID,并且生成一个read view,包含了当前系统的活跃事务ID列表,以RR隔离级别下,MVCC行为
1. 插入操作将记录的创建版本号赋值为当前版本
2. 删除操作将记录的删除版本号赋值为当前事务ID
3 更新操作将当前记录标识成删除,删除版本号赋值为当前事务ID,并且新创建一条记录,新纪录的创建版本号赋值成当前事务ID
4.select操作需要避免脏读,不可重复度,因此读取的数据需要包括在事务开启之前没有改变过,或者事务开启之后才被删除的,delete_version==null && create_version<up_limit_tid 或者 delete_version>up_limit_tid
RC中的MVCC行为只是read view在每次执行读之前都会更新,因此会读取到最新的commit的事务做出的修改。
MVCC实现了并发地无阻塞读,这个无阻塞读实际上是快照读,不加锁,
如简单的
- select * from xxx where ?
相对快照读还有当前读,当前读是需要加锁的:
- select * from table where ? lock in share mode;
- select * from table where ? for update;
- insert into table values (…);
- update table set ? where ?;
- delete from table where ?;
在MVCC的支持下各个隔离级别加锁情况如下:
Read Committed (RC)
快照读不加锁
针对当前读,RC隔离级别保证对读取到的记录加锁 (记录锁),存在幻读现象。
如果一个更新,或删除语句没有走索引,RC会对全表加锁,然后对不满足条件的记录再进行解锁,这实际上mysql为了效率违背了两阶段锁协议的规范,
Repeatable Read (RR)
快照读不加锁
针对当前读,RR隔离级别保证对读取到的记录加锁 (记录锁),同时保证对读取的范围加锁,新的满足查询条件的记录不能够插入 (间隙锁),不存在幻读现象。
丢失更新的解决方式:
丢失更新发生的根本原因是基于相同的版本的数据的写操作都允许成功,乐观锁能够避免第一类和第二类丢失更新
1.悲观锁的方式: slect * from table for update;
2.乐观锁版本号的方式
拍卖相关
事务的隔离级别的选择:
有可重复读的需求,无防止幻读的需求,需要防止丢失更新;
1.乐观锁解决丢失更新问题
2.定制化的更新接口解决可重复读需求,这种方法一定情况下也可以解决幻读问题
通过这些办法使得隔离级别在RC下也能满足需求,相比RR没有间隙锁,能提高系统的并发能力
保证金临界状态
根本的解决办法只有使用悲观锁
如果有高并发的场景价格的乐观锁可以写成类似库存的方案
在更新拍品记录的语句中将乐观锁版本号的比较改成 bid_price>current_price and status>'bidding',这样在出价价格比较分散的情况下能够一定程度提高系统并发能力,在用版本号做为乐观锁的情况下,用户A出价1000,用户B出价2000,当用户A和用户B冲突并且A抢先更新了乐观锁,B的出价就会失败,哪怕B出价更高。
拍卖系统数据库高可用方案
数据库高可用方案:
- 一写多读:单master(负责写),多slave(负责读)当做了一写多读后,因为从多个读库中均衡读取数据,如果某一台读库宕机,那么隔离屏蔽,这样就做到了读的高可用。但写库还是一个单点,并且读库和写库之间数据同步有一定延迟。这种方案一旦master挂掉了拍卖的竞拍业务也就挂了,导购相关的读业务还能继续提供服务;
- 主库冷备+多读:正常工作的时候同一写多读一样,当主库发生故障,写切换到备份机上,这时候对于新数据的写可以继续,对于历史数据的读也可以继续,对于历史数据的更新可能无法进行,当主库故障,业务很大程度上能够继续,不至于完全挂掉,这种部署方式对于一口价这样的业务基本是可行的,但是拍卖的出价是一个强一致上下文相关的过程,凡是读写分离的方式主备之间可能存在数据不一致的方案都不能采用
- 双master:同时存在两个master提供写,master之间采用数据强同步,这样能够做到一个写节点挂了另一个节点就能顶上去。缺点是两个master之间的数据同步超时或者抖动当次业务处理就可能判定为失败,因此双master的重点是两个master所在的机房距离尽可能近,阿里机房距离在50km以内的差不多延迟在1-2ms,如果800km就可能达到几十ms,一次出价操作涉及到5次左右的数据写,如果距离近差不多增加10-20ms左右的延迟,问题不是很大;
- 三master:在数据同步上当前master向两个stand by的master做数据强同步,只要有其中一个成功了就可以返回,在机房之间网络出现波动的时候可以提高一定的可用性,数据延迟也不会增加
相关推荐
在数据库管理系统中,事务和锁是两个至关重要的概念,它们主要用于保证数据的一致性和完整性,以及在多用户环境下的并发访问控制。 事务是数据库操作的基本单位,它封装了一组数据库操作,这些操作要么全部执行,...
数据库事务是数据库操作的核心组成部分,它确保了数据的一致性和完整性。事务是由一系列数据库操作组成的逻辑单元,这些操作要么全部成功执行,要么全部不执行,遵循ACID(原子性、一致性、隔离性和持久性)原则。 ...
### 数据库事务及锁机制详解 #### 一、事务的概念与特性 事务是数据库系统中一组操作的集合,用于确保数据的一致性和完整性。在事务处理中,事务被视为一个不可分割的工作单元,其中包含的操作要么全部成功,要么...
数据库安全事务与锁是数据库管理系统中的关键概念,它们确保了多用户环境下数据的一致性和完整性。在SQL Server 2000中,事务和锁机制对于保证数据库系统的并发操作和数据安全性至关重要。 1. **事务**: 事务是...
### 数据库事务总结 #### 一、事务的基本概念与特性 **事务**是数据库系统中的一个逻辑工作单元,它由一系列的操作组成,这些操作要么都完成,要么都不完成,以此来保证数据的一致性和完整性。 #### 二、事务的...
数据库事务管理及锁机制原理剖析:包括事务特性 ACID、数据隔离级别、事务实现的原理、锁机制,及过程中可能遇到的查询效率及死锁问题等
锁机制可以在不同的粒度上生效,包括表锁、页锁和行锁。 锁表查询是指通过查询数据库锁信息来了解当前数据库中的锁状态。锁表查询可以帮助数据库管理员了解当前数据库中的锁情况,从而进行锁优化和故障诊断。 下面...
在介绍SQL Server数据库事务锁机制之前,首先需要了解锁的概念。锁是网络数据库中的一个非常重要的概念,主要用于在多用户环境下保证数据库的完整性和一致性。锁通过指示某个用户(即进程会话)已经占用了某种资源,...
MS SQL Server 数据库的事务锁机制是确保数据库完整性和一致性的关键组成部分,它涉及到多用户环境下的并发控制和数据安全。锁是一种软件机制,用于防止多个用户在同一时间对同一资源进行冲突操作,确保数据的一致性...
一次长事务可能会占用大量资源,导致其他并发事务出现锁等待,甚至超时,严重影响数据库的性能和正常服务。本篇文章将深入探讨这个问题,从原因、表现、诊断到解决策略进行详细分析。 一、长事务的定义与特征 长...
详细描述数据库锁和事务的内容,其中包括各种类型的锁的讲述,事务的控制
数据库之事务调优是数据库管理中的一个重要环节,它关乎到系统的性能、稳定性和并发处理能力。事务是数据库操作的基本单位,确保数据的一致性、...通过这些方法,我们可以构建出一个高效、稳定的数据库事务处理系统。
博客的代码,查看当前导致数据库锁的具体sql语句,调查代码逻辑死锁导致数据库超时的例子,对应的博客文章位置http://blog.csdn.net/pfe_nova/article/details/9055981 注意将代码配置文件的连接字符串改成自己实际...
5. **页级锁(Page-Level Locks)**:锁定数据库的一页数据,介于行级锁和表级锁之间。 6. **死锁(Deadlock)**:当两个或更多事务相互等待对方释放资源而形成的一种僵局,需要通过特定算法来检测和解决。 在实际...
Oracle数据库使用行级锁和块级锁,并提供一种称为Next-Key Locks的机制,防止幻读问题。 总的来说,数据库中的锁机制是保证数据安全和事务正确执行的关键。通过理解不同类型的锁和它们在不同隔离级别下的行为,...
【数据库系统工程师-06事务和锁】 在数据库系统中,事务和锁是核心概念,它们对于确保数据的完整性和一致性至关重要。事务是一系列数据库操作的逻辑单元,它具有四个关键特性,通常被称为ACID特性。 1. **原子性...