当前位置: 首页 > news >正文

网站建设服务有哪些内容导购类网站怎么做

网站建设服务有哪些内容,导购类网站怎么做,北京公司网站如何制作,坦洲网站建设公司哪家好3.2 从数据操作的粒度划分#xff1a;表级锁、页级锁、行锁 为了提高数据库并发度#xff0c;每次锁定的数据范围越小越好#xff0c;理论上每次只锁定当前操作的数据的方案会得到最大的并发度#xff0c;但管理锁是很耗资源#xff08;涉及获取、检查、释放锁等动作)。因…3.2 从数据操作的粒度划分表级锁、页级锁、行锁 为了提高数据库并发度每次锁定的数据范围越小越好理论上每次只锁定当前操作的数据的方案会得到最大的并发度但管理锁是很耗资源涉及获取、检查、释放锁等动作)。因此数据库系统需要在高并发响应和系统性能两方面进行平衡这样就产生了“锁粒度(Lock granularity)”的概念。 对一条记录加锁影响的也只是这条记录而已我们就说这个锁的粒度比较细;其实一个事务也可以在表级别进行加锁自然就被称之为表级锁或者表锁对一个表加锁影响整个表中的记录我们就说这个锁的粒度比较粗。锁的粒度主要分为表级锁、页级锁和行锁。 1. 表锁Table Lock 该锁会锁定整张表它是MysQL中最基本的锁策略并不依赖于存储引擎不管你是MysQL的什么存储引擎对于表锁的策略都是一样的)并且表锁是开销最小的策略因为粒度比较大)。由于表级锁一次会将整个表锁定所以可以很好的避免死锁问题。当然锁的粒度大所带来最大的负面影响就是出现锁资源争用的概率也会最高导致并发率大打折扣。 ① 表级别的S锁、X锁  在对某个表执行 SELECT 、 INSERT 、 DELETE 、 UPDATE 语句时 InnoDB 存储引擎是不会为这个表添加表级别的 S 锁 或者 X 锁 的。在对某个表执行一些诸如 alter table 、 drop table  这类的 DDL 语句时其他事务对这个表并发执行诸如select 、 insert 、 delete 、 update的语句会发生阻塞。同理某个事务中对某个表执行select 、 insert 、 delete 、 update 语句时在其他会话中对这个表执行 DDL 语句也会发生阻塞。这个过程其实是通过在 server 层 使用一种称之为 元数据锁 英文名 Metadata Locks 简称 MDL 结构来实现的(总之就是宁可用元数据锁也不用表级别的S 锁、X锁)。 innodb只会在一些特殊情况下比方说 崩溃恢复 过程中用到。在系统变量 autocommit0 innodb_table_locks 1 时 手动 获取InnoDB存储引擎提供的表 t 的 S 锁 或者 X 锁 可以这么写 lock tables t read  InnoDB 会对表 t 加表级别的 S 锁  lock tables t write  InnoDB 会对表 t 加表级别的 X 锁  不过尽量避免在使用 InnoDB 存储引擎的表上使用 LOCK TABLES 这样的手动锁表语句它们并不会提供什么额外的保护只是会降低并发能力而已。InnoDB 的厉害之处还是实现了更细粒度的 行锁 关于 InnoDB表级别的 S 锁 和 X 锁 大家了解一下就可以了。 总结 :  MyISAM 在执行查询语句(select)前, 会给涉及的所有表加读锁, 在执行增删改操作前, 会给涉及的表加写锁, InnoDB 存储引擎是不会为这个表添加表级锁的 读锁 和 写锁 的(因为InnoDB实现了行锁) ② 意向锁 intention lock InnoDB 支持 多粒度锁 multiple granularity locking 它允许 行级锁 与 表级锁 共存而 意向 锁 就是其中的一种 表锁 。 1. 意向锁的存在是为了协调行锁和表锁的关系, 支持多粒度(表锁与行锁)的锁并存 2. 意向锁是一种不与行级锁冲突的表级锁, 这点非常重要 3. 表明某个事务正在某些行持有了锁或该事务准备去持有锁  意向锁分为两种 ① 意向共享锁 intention shared lock, IS 事务有意向对表中的某些行加 共享锁 S 锁 -- 事务要获取某些行的 S 锁必须先获得表的 IS 锁。 SELECT column FROM table ... LOCK IN SHARE MODE;      ②意向排他锁intention exclusive lock, IX事务有意向对表中的某些行加排他锁X锁 -- 事务要获取某些行的 X 锁必须先获得表的 IX 锁。 SELECT column FROM table ... FOR UPDATE; 即意向锁是由存储引擎 自己维护的 用户无法手动操作意向锁在为数据行加共享 / 排他锁之前 InooDB 会先获取该数据行 所在数据表的对应意向锁 。 1. 意向锁要解决的问题 现在有两个事务分别是T1和T2其中T2试图在该表级别上应用共享或排它锁如果没有意向锁存在那么T2就需要去检查各个页或行是否存在锁;如果存在意向锁那么此时就会受到由T1控制的 表级别意向锁的阻塞 。T2在锁定该表前不必检查各个页或行锁而只需检查表上的意向锁。简单来说就是给更大一级别的空间示意里面是否已经上过锁。 在数据表的场景中 如果我们给某一行数据加上了排它锁数据库会自动给更大一级的空间比如数据页或数据表加上意向锁告诉其他人这个数据页或数据表已经有人上过排它锁了 这样当其他人想要获取数据表排它锁的时候只需要了解是否有人已经获取了这个数据表的意向排他锁即可。   ① 如果事务想要获得数据表中某些记录的共享锁就需要在数据表上添加 意向共享锁 。 ② 如果事务想要获得数据表中某些记录的排他锁就需要在数据表上添加 意向排他锁 。 这时意向锁会告诉其他事务已经有人锁定了表中的某些记录。 举例:   因为共享锁与排他锁互斥所以事务B在试图对teacher表加共享锁的时候必须保证两个条件。 (1当前没有其他事务持有teacher表的排他锁 (2当前没有其他事务持有teacher表中任意一行的排他锁。 为了检测是否满足第二个条件事务B必须在确保teacher表不存在任何排他锁的前提下去检测表中的每一行是否存在排他锁。 很明显这是一个效率很差的做法但是有了意向锁之后情况就不一样了。 意向锁是怎么解决这个问题的呢?首先我们需要知道意向锁之间的兼容互斥性如下所示。 即 意向锁之间是互相兼容的(虽然是表级的,但描述的是行级上锁情况)虽然意向锁和自家兄弟互相兼容但是它会与普通的排他/共享锁互斥。 注意这里的排他/共享锁指的都是表锁 意向锁不会与行级的共享/排他锁互斥。回到刚才teacher 表的例子。   意向锁的并发性 意向锁不会与行级的共享 / 排他锁互斥正因为如此意向锁并不会影响到多个事务对不同数据行加排 他锁时的并发性。不然我们直接用普通的表锁就行了 我们扩展一下上面 teacher 表的例子来概括一下意向锁的作用一条数据从被锁定到被释放的过程中可 能存在多种不同锁但是这里我们只着重表现意向锁。 从上面的案例可以得到如下结论 1. InnoDB 支持 多粒度锁 特定场景下行级锁可以与表级锁共存。 2. 意向锁之间互不排斥但除了 IS 与 S 兼容外 意向锁会与 共享锁 / 排他锁 互斥 。 3. IX IS 是表级锁不会和行级的 X S 锁发生冲突。只会和表级的 X S 发生冲突。 4. 意向锁在保证并发性的前提下实现了 行锁和表锁共存 且 满足事务隔离性 的要求。 ③ 元数据锁MDL锁  MySQL5.5 引入了 meta data lock 简称 MDL 锁属于表锁范畴。 MDL 的作用是保证读写的正确性。比 如如果一个查询正在遍历一个表中的数据而执行期间另一个线程对这个 表结构做变更 增加了一列那么查询线程拿到的结果跟表结构对不上肯定是不行的。 因此 当对一个表做增删改查操作的时候加 MDL 读锁当要对表做结构变更操作的时候加 MDL 写 锁。 读锁之间不互斥因此你可以有多个线程同时对一张表增删改查。读写锁之间、写锁之间是互斥的用来保证变更表结构操作的安全性解决了DML和DDL操作之间的一致性问题。 不需要显式使用 在访问一个表的时候会被自动加上。 2. InnoDB中的行锁  行锁(Row Lock)也称为记录锁顾名思义就是锁住某一行某条记录row)。需要的注意的是MySQL服务器层并没有实现行锁机制行级锁只在存储引擎层实现。优点:锁定力度小发生锁冲突概率低可以实现的并发度高。 缺点:对于锁的开销比较大加锁会比较慢容易出现死锁情况。 InnoDB与MyISAM的最大不同有两点:一是支持事务(TRANSACTION);二是采用了行级锁。 先建立student表 ① 记录锁Record Locks 记录锁也就是仅仅把一条记录锁上官方的类型名称为 LOCK_REC_NOT_GAP 。比如我们把 id 值为 8 的那条记录加一个记录锁的示意图如图所示。仅仅是锁住了id 值为8的记录对周围的数据没有影响。 举例如下 记录锁是有 S 锁和 X 锁之分的称之为 S 型记录锁 和 X 型记录锁 。 当一个事务获取了一条记录的S型记录锁后其他事务也可以继续获取该记录的S型记录锁但不可 以继续获取X型记录锁 当一个事务获取了一条记录的X型记录锁后其他事务既不可以继续获取该记录的S型记录锁也不可以继续获取X型记录锁。 ② 间隙锁Gap Locks MySQL 在 REPEATABLE READ 隔离级别下是可以解决幻读问题的解决方案有两种可以使用 MVCC 方案解决也可以采用 加锁 方案解决。但是在使用加锁方案解决时有个大问题就是事务在第一次执行读取操作时那些幻影记录尚不存在我们无法给这些 幻影记录 加上 记录锁 。 InnoDB 提出了一种称之为 Gap Locks 的锁官方的类型名称为 LOCK_GAP 我们可以简称为 gap 锁 。比如把 id 值为 8 的那条记录加一个gap 锁的示意图如下。 图中 id 值为 8 的记录加了 gap 锁意味着 不允许别的事务在 id 值为 8 的记录前边的间隙插入新记录 其实就是id列的值 (3, 8) 这个区间的新记录是不允许立即插入的。比如有另外一个事务再想插入一条 id 值为 4 的新记录它定位到该条新记录的下一条记录的id 值为 8 而这条记录上又有一个 gap 锁所以就会阻塞插入操作直到拥有这个gap 锁的事务提交了之后 id 列的值在区间 (3, 8) 中的新记录才可以被插入。 gap 锁的提出仅仅是为了防止插入幻影记录而提出的 。 间隙锁的引入,可能会导致同样的语句锁住更大的范围, 这其实是影响了并发度的, 下面的例子会产生死锁 session 1 执行select ... for update 语句, 由于id 5 这一行并不存在, 因此会加上间隙锁(3,8) session 2 执行select ... for update 语句, 同样加上间隙锁(3,8), 间隙锁之间不会冲突, 因此这个语句可以执行成功session 2 试图插入一行, 被session 1 的间隙锁挡住,进入等待session 1 视图插入一行, 被session 2 的间隙锁挡住, 两个session进入死锁 ③ 临键锁Next-Key Locks 记录锁 间隙锁 ④ 插入意向锁Insert Intention Locks 我们说一个事务在 插入 一条记录时需要判断一下插入位置是不是被别的事务加了 gap 锁 next - key 锁 也包含 gap 锁 如果有的话插入操作需要等待直到拥有 gap 锁 的那个事务提交。但是 InnoDB 规 定事务在等待的时候也需要在内存中生成一个锁结构 表明有事务想在某个 间隙 中 插入 新记录但是 现在在等待。InnoDB 就把这种类型的锁命名为 Insert Intention Locks 官方的类型名称为 LOCK_INSERT_INTENTION 我们称为 插入意向锁 。插入意向锁是一种 Gap 锁 不是意向锁在 insert操作时产生。 插入意向锁是在插入一条记录行前由INSERT操作产生的一种间隙锁。该锁用以表示插入意向, 当多个事务在同一区间(gap插入位置不同的多条数据时事务之间不需要互相等待。假设存在两条值分别为4和7的记录两个不同的事务分别试图插入值为5和6的两条记录每个事务在获取插入行上独占的(排他锁前都会获取(47之间的间隙锁但是因为数据行之间并不冲突所以两个事务之间并不会产生冲突(阻塞等待)。 总结来说插入意向锁的特性可以分成两部分: 插入意向锁是一种特殊的间隙锁—―间隙锁可以锁定开区间内的部分记录。插入意向锁之间互不排斥所以即使多个事务在同一区间插入多条记录只要记录本身(主键、唯一索引)不冲突那么事务之间就不会出现冲突等待。 注意虽然插入意向锁中含有意向锁三个字但是它并不属于意向锁而属于间隙锁因为意向锁是表锁而插入意向锁是行锁。 比如把id值为8的那条记录加一个插入意向锁的示意图如下:比如, 现在T1为id值为8 的记录加了一个gap锁, 然后T2 和 T3 分别想向student表中插入id值分别为4,5的两条记录, 所以现在为id值为8的记录加的锁的示意图就如下所示: 从图中可以看到由于T1持有gap锁所以T2和T3需要生成一个插入意向锁的锁结构并且处于等待状态。当T1提交后会把它获取到的锁都释放掉这样T2和T3就能获取到对应的插入意向锁了(本质上就是把插入意向锁对应锁结构的is_waiting属性改为false)T2和T3之间也并不会相互阻塞它们可以同时获取到id值为8的插入意向锁,然后执行插入操作。事实上插入意向锁并不会阻止别的事务继续获取该记录上任何类型的锁。 3.3 从对待锁的态度划分:乐观锁、悲观锁 从对待锁的态度来看锁的话可以将锁分成乐观锁和悲观锁从名字中也可以看出这两种锁是两种看待 数据并发的思维方式 。需要注意的是乐观锁和悲观锁并不是锁而是锁的 设计思想 。 1. 悲观锁Pessimistic Locking 悲观锁是一种思想顾名思义就是很悲观对数据被其他事务的修改持保守态度会通过数据库自身的锁机制来实现从而保证数据操作的排它性。 悲观锁总是假设最坏的情况每次去拿数据的时候都认为别人会修改所以每次在拿数据的时候都会上锁这样别人想拿这个数据就会 阻塞 直到它拿到锁 共享资源每次只给一个线程使用其它线程阻塞 用完后再把资源转让给其它线程 。比如行锁表锁等读锁写锁等都是在做操作之前先上锁当其他线程想要访问数据时都需要阻塞挂起。Java 中 synchronized 和 ReentrantLock 等独占锁就是悲观锁思想的实现。 2. 乐观锁Optimistic Locking 乐观锁认为对同一数据的并发操作不会总发生属于小概率事件不用每次都对数据上锁但是在更新的时候会判断一下在此期间别人有没有去更新这个数据也就是 不采用数据库自身的锁机制而是通过 程序来实现 。在程序上我们可以采用 版本号机制 或者 CAS 机制 实现。 乐观锁适用于多读的应用类型 这样可以提高吞吐量 。在 Java 中 java.util.concurrent.atomic 包下的原子变量类就是使用了乐观锁 的一种实现方式 CAS 实现的。 1. 乐观锁的版本号机制 在表中设计一个 版本字段 version 第一次读的时候会获取 version 字段的取值。然后对数据进行更新或删除操作时会执行 UPDATE ... SET versionversion1 WHERE versionversion 。此时如果已经有事务对这条数据进行了更改修改就不会成功。 2. 乐观锁的时间戳机制 时间戳和版本号机制一样也是在更新提交的时候将当前数据的时间戳和更新之前取得的时间戳进行比较如果两者一致则更新成功否则就是版本冲突。 你能看到乐观锁就是程序员自己控制数据并发操作的权限基本是通过给数据行增加一个戳版本号或者时间戳从而证明当前拿到的数据是否最新。 3. 两种锁的适用场景 从这两种锁的设计思想中我们总结一下乐观锁和悲观锁的适用场景 乐观锁 适合 读操作多 的场景相对来说写的操作比较少。它的优点在于 程序实现 不存在死锁 问题不过适用场景也会相对乐观因为它阻止不了除了程序以外的数据库操作。 悲观锁 适合 写操作多 的场景因为写的操作具有 排它性 。采用悲观锁的方式可以在数据库层面阻止其他事务对该数据的操作权限防止 读 - 写 和 写 - 写 的冲突。 3.4 其它锁之全局锁 全局锁就是对 整个数据库实例 加锁。当你需要让整个库处于 只读状态 的时候可以使用这个命令之后其他线程的以下语句会被阻塞数据更新语句数据的增删改、数据定义语句包括建表、修改表结构等和更新类事务的提交语句。全局锁的典型使用 场景 是做 全库逻辑备份 。 全局锁的命令 Flush tables with read lock 3.5 其它锁之死锁 1. 概念 死锁是指两个或多个事务都持有对方需要的锁, 并且在等待对方释放, 并且双方都不会释放自己的锁。 死锁示例 这时候事务1在等待事务2释放id2的行锁而事务2在等待事务1释放id1的行锁。 事务1和事务2在互相等待对方的资源释放就是进入了死锁状态。当出现死锁以后有 两种策略 一种策略是直接进入等待直到超时。这个超时时间可以通过参数 innodb_lock_wait_timeout 来设置。 另一种策略是发起死锁检测发现死锁后主动回滚死锁链条中的某一个事务将持有最少行级排他锁的事务进行回滚让其他事务得以继续执行。将参数 innodb_deadlock_detect 设置为 on 表示开启这个逻辑。 2. 产生死锁的必要条件 两个或者两个以上事务每个事务都已经持有锁并且申请新的锁锁资源同时只能被同一个事务持有或者不兼容事务之间因为持有锁和申请锁导致彼此循环等待 死锁的关键在于:两个(或以上)的Session加锁的顺序不一致。 3.如何处理死锁 方式1:等待直到超时(innodb_lock_wait_timeout50s)。 即当两个事务互相等待时当一个事务等待时间超过设置的阈值时就将其回滚另外事务继续进行。这种方法简单有效在innodb中参数innodb_lock_wait_timeout用来设置超时时间。 缺点:对于在线服务来说这个等待时间往往是无法接受的。 那将此值修改短一些比如1s0.1s是否合适?不合适容易误伤到普通的锁等待。 方式2:使用死锁检测进行死锁处理 方式1检测死锁太过被动innodb还提供了wait-for graph算法来主动进行死锁检测每当加锁请求无法立即满足需要并进入等待时wait-for graph算法都会被触发。 基于这两个信息, 可以绘制wait-for graph(等待图) 死锁检测的原理是构建一个以事务为顶点, 锁为边的有向图,判断有向图是否存在环, 存在即有锁 一旦检测到回路、有死锁这时候InnoDB存储引擎会选择回滚undo量最小的事务(将持有最少行级排他锁的事务进行回滚)让其他事务继续执行(innodb_deadlock_detecton 表示开启这个逻辑)。 缺点:每个新的被阻塞的线程都要判断是不是由于自己的加入导致了死锁这个操作时间复杂度是o(n)。如果100个并发线程同时更新同一行意味着要检测100*100 1万次1万个线程就会有1千万次检测。 如何解决? 方式1:关闭死锁检测但意味着可能会出现大量的超时会导致业务有损。方式2:控制并发访问的数量。比如在中间件中实现对于相同行的更新在进入引擎之前排队这样在InnoD内部就不会有大量的死锁检测工作。   进一步的思路: 可以考虑通过将一行改成逻辑上的多行来减少锁冲突. 比如, 连锁超市账户总额的记录, 可以考虑放到多条记录上, 账户总额等于这多个记录的值的总和. 4.如何避免死锁 合理设计索引使业务sQL尽可能通过索引定位更少的行减少锁竞争。 调整业务逻辑sQL执行顺序避免update/delete长时间持有锁的sQL在事务前面。 避免大事务尽量将大事务拆成多个小事务来处理小事务缩短锁定资源的时间发生锁冲突的几率也更小。 在并发比较高的系统中不要显式加锁特别是是在事务里显式加锁。如select ... for update语句如果是在事务里运行了start transaction或设置了autocommit等于o那么就会锁定所查找到的记录。 降低隔离级别。如果业务允许将隔离级别调低也是较好的选择比如将隔离级别从RR调整为Rc可以避免掉很多因为gap锁造成的死锁。
http://www.yutouwan.com/news/366493/

相关文章:

  • 一个网站同时做竞价和seo宁波网站开发建设
  • 搭建网站的流程计算机类十大含金量证书
  • 做直播网站找哪家网站百度关键词怎么做
  • 网站建设绵阳免费俄罗斯网站制作
  • 网络公司网站报价方案网站定制二次开发
  • 企业网站建设与实施调查报告企业型网站
  • 网站建设的方案阿里虚拟主机无法安装wordpress
  • 广州网络推广建站wordpress在线支付插件
  • 如何做淘宝的站外网站推广室内设计师常用网站
  • 哪家公司做跳转网站企业网站建设论文文献综述
  • 自助建站是什么意思著名平面设计师及作品欣赏
  • 网站开发公司报价甘肃省城乡与住房建设厅网站
  • 滕州 网站 建设神一般的网页设计网站
  • 网站代理软件深圳设计公司名字
  • 外贸公司访问国外网站wordpress去掉版本号
  • 沧州网站优化成都搜索优化排名公司
  • 贵阳手机端网站建设公司网络部署方案
  • 北京网站的制作设计网页设计于制作课程标准
  • 河南省建设工程招投标协会网站客户营销
  • 营销网站的筛选北滘禅城网站建设
  • 运城建设网站秦皇岛网站建设报价
  • 模具东莞网站建设品牌的手机网站制作
  • 做网站原型图网页版传奇如何作弊?
  • 做游戏女角色去衣的网站软件ui设计培训学校
  • 网络维护网站wordpress社团网站
  • 九号线香网站建设杭州门户网站有哪些
  • cms管理手机网站启博云微分销
  • 建站系统是什么私人定制
  • 江阴网站建设多少钱杭州协会网站建设
  • 佛山营销型网站建设公司公众号制作链接教程