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

学做网站视频wordpress主题模板视频网站

学做网站视频,wordpress主题模板视频网站,wordpress多说评论插件,山西省消防总队建设工程备案网站数据库大并发操作要考虑死锁和锁的性能问题。用T1代表一个数据库执行请求#xff0c;T2代表另一个请求#xff0c;也可以理解为T1为一个线程#xff0c;T2 为另一个线程。T3,T4以此类推。下面以SQL Server为例。 锁的种类 共享锁(Shared lock) 例1#xff1a;T1: select…数据库大并发操作要考虑死锁和锁的性能问题。用T1代表一个数据库执行请求T2代表另一个请求也可以理解为T1为一个线程T2 为另一个线程。T3,T4以此类推。下面以SQL Server为例。 锁的种类 共享锁(Shared lock) 例1T1: select * from table (请想象它需要执行1个小时之久后面的sql语句请都这么想象T2: update table set column1hello过程 T1运行 加共享锁) T2运行 If T1 还没执行完 T2等...... else 锁被释放 T2执行 endif T2之所以要等是因为T2在执行update前试图对table表加一个排他锁而数据库规定同一资源上不能同时共存共享锁和排他锁。所以T2必须等T1执行完释放了共享锁才能加上排他锁然后才能开始执行update语句。例2T1: select * from tableT2: select * from table这里T2不用等待T1执行完而是可以马上执行。分析T1运行则table被加锁比如叫lockAT2运行再对table加一个共享锁比如叫lockB。两个锁是可以同时存在于同一资源上的比如同一个表上。这被称为共享锁与共享锁兼容。这意味着共享锁不阻止其它session同时读资源但阻止其它session update例3T1: select * from tableT2: select * from tableT3: update table set column1hello这次T2不用等T1运行完就能运行T3却要等T1和T2都运行完才能运行。因为T3必须等T1和T2的共享锁全部释放才能进行加排他锁然后执行update操作例4死锁的发生 T1: begin tran select * from table (holdlock) (holdlock意思是加共享锁直到事务结束才释放) update table set column1helloT2: begin tran select * from table(holdlock) update table set column1world 假设T1和T2同时达到selectT1对table加共享锁T2也对加共享锁当T1的select执行完准备执行update时根据锁机制T1的共享锁需要升级到排他锁才能执行接下来的update.在升级排他锁前必须等table上的其它共享锁释放但因为holdlock这样的共享锁只有等事务结束后才释放所以因为T2的共享锁不释放而导致T1等(等T2释放共享锁自己好升级成排他锁同理也因为T1的共享锁不释放而导致T2等。死锁产生了。例5 T1: begin tran update table set column1hello where id10T2: begin tran update table set column1world where id20 这种语句虽然最为常见很多人觉得它有机会产生死锁但实际上要看情况如果id是主键上面有索引那么T1会一下子找到该条记录(id10的记录然后对该条记录加排他锁T2同样一下子通过索引定位到记录然后对id20的记录加排他锁这样T1和T2各更新各的互不影响。T2也不需要等。但如果id是普通的一列没有索引。那么当T1对id10这一行加排他锁后T2为了找到id20需要对全表扫描那么就会预先对表加上共享锁或更新锁或排他锁(依赖于数据库执行策略和方式比如第一次执行和第二次执行数据库执行策略就会不同。但因为T1已经为一条记录加了排他锁导致T2的全表扫描进行不下去就导致T2等待 死锁怎么解决呢一种办法是如下 例6 T1: begin tran select * from table(xlock) (xlock意思是直接对表加排他锁) update table set column1hello T2: begin tran select * from table(xlock) update table set column1world 这样当T1的select 执行时直接对表加上了排他锁T2在执行select时就需要等T1事物完全执行完才能执行。排除了死锁发生。 但当第三个user过来想执行一个查询语句时也因为排他锁的存在而不得不等待第四个、第五个user也会因此而等待。在大并发 情况下让大家等待效果可想而知所以这里引入了更新锁。 更新锁(Update lock) 为解决死锁引入更新锁。 例7 ---------------------------------------- T1: begin tran select * from table(updlock) (加更新锁) update table set column1hello T2: begin tran select * from table(updlock) update table set column1world 更新锁的意思是“我现在只想读你们别人也可以读但我将来可能会做更新操作我已经获取了从共享锁用来读到排他锁 用来更新的资格”。一个事务只能有一个更新锁获此资格。 T1执行select加更新锁。 T2运行准备加更新锁但发现已经有一个更新锁在那儿了只好等。 当后来有user3、user4...需要查询table表中的数据时并不会因为T1的select在执行就被阻塞照样能查询相比起例6这提高 了效率。 例8: ---------------------------------------- T1: select * from table(updlock) (加更新锁 T2: select * from table(updlock) (等待直到T1释放更新锁因为同一时间不能在同一资源上有两个更新锁 T3: select * from table (加共享锁但不用等updlock释放就可以读 这个例子是说明共享锁和更新锁可以同时在同一个资源上。这被称为共享锁和更新锁是兼容的。 例9: ---------------------------------------- T1: begin select * from table(updlock) (加更新锁 update table set column1hello (重点这里T1做update时不需要等T2释放什么而是直接把更新锁升级为排他锁然后执行update) T2: begin select * from table (T1加的更新锁不影响T2读取 update table set column1world (T2的update需要等T1的update做完才能执行) 我们以这个例子来加深更新锁的理解 第一种情况T1先达T2紧接到达在这种情况中T1先对表加更新锁T2对表加共享锁假设T2的select先执行完准备执行update 发现已有更新锁存在T2等。T1执行这时才执行完select准备执行update更新锁升级为排他锁然后执行update执行完成事务 结束释放锁T2才轮到执行update。 第二种情况T2先达T1紧接达在这种情况T2先对表加共享锁T1达后T1对表加更新锁假设T2 select先结束准备 update发现已有更新锁则等待后面步骤就跟第一种情况一样了。 这个例子是说明排他锁与更新锁是不兼容的它们不能同时加在同一子资源上。 排他锁独占锁Exclusive Locks) 这个简单即其它事务既不能读又不能改排他锁锁定的资源。 例10 T1: update table set column1hello where id1000 T2: update table set column1world where id1000 假设T1先达T2随后至这个过程中T1会对id1000的记录施加排他锁.但不会阻塞T2的update。 例11 (假设id都是自增长且连续的 T1: update table set column1hello where id1000 T2: update table set column1world where id900 如同例10T1先达T2立刻也到T1加的排他锁会阻塞T2的update. 意向锁(Intent Locks) 意向锁就是说在屋比如代表一个表门口设置一个标识说明屋子里有人比如代表某些记录被锁住了。另一个人想知道屋子 里是否有人被锁不用进屋子里一个一个的去查直接看门口标识就行了。 当一个表中的某一行被加上排他锁后该表就不能再被加表锁。数据库程序如何知道该表不能被加表锁一种方式是逐条的判断该 表的每一条记录是否已经有排他锁另一种方式是直接在表这一层级检查表本身是否有意向锁不需要逐条判断。显然后者效率高。 例12 ---------------------------------------- T1: begin tran select * from table (xlock) where id10 --意思是对id10这一行强加排他锁 T2: begin tran select * from table (tablock) --意思是要加表级锁 假设T1先执行T2后执行T2执行时欲加表锁为判断是否可以加表锁数据库系统要逐条判断table表每行记录是否已有排他锁 如果发现其中一行已经有排他锁了就不允许再加表锁了。只是这样逐条判断效率太低了。 实际上数据库系统不是这样工作的。当T1的select执行时系统对表table的id10的这一行加了排他锁还同时悄悄的对整个表 加了意向排他锁(IX)当T2执行表锁时只需要看到这个表已经有意向排他锁存在就直接等待而不需要逐条检查资源了。 例13 ---------------------------------------- T1: begin tran update table set column1hello where id1 T2: begin tran update table set column1world where id1 这个例子和上面的例子实际效果相同T1执行系统对table同时对行加排他锁、对页加意向排他锁、对表加意向排他锁。 计划锁(Schema Locks) 例14 ---------------------------------------- alter table .... (加schema locks称之为Schema modification (Sch-M) locks DDL语句都会加Sch-M锁 该锁不允许任何其它session连接该表。连都连不了这个表了当然更不用说想对该表执行什么sql语句了。 例15: ---------------------------------------- 用jdbc向数据库发送了一条新的sql语句数据库要先对之进行编译在编译期间也会加锁称之为Schema stability (Sch-S) locks select * from tableA 编译这条语句过程中其它session可以对表tableA做任何操作(update,delete加排他锁等等但不能做DDL(比如alter table)操作。 Bulk Update Locks 主要在批量导数据时用比如用类似于oracle中的imp/exp的bcp命令。不难理解程序员往往也不需要关心不赘述了。 3 何时加锁 如何加锁何时加锁加什么锁你可以通过hint手工强行指定但大多是数据库系统自动决定的。这就是为什么我们可以不懂锁也可 以高高兴兴的写SQL。 例15: ---------------------------------------- T1: begin tran update table set column1hello where id1 T2: SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED -- 事务隔离级别为允许脏读 go select * from table where id1 这里T2的select可以查出结果。如果事务隔离级别不设为脏读则T2会等T1事物执行完才能读出结果。 数据库如何自动加锁的 1) T1执行数据库自动加排他锁 2) T2执行数据库发现事务隔离级别允许脏读便不加共享锁。不加共享锁则不会与已有的排他锁冲突所以可以脏读。 例16: ---------------------------------------- T1: begin tran update table set column1hello where id1 T2: select * from table where id1 --为指定隔离级别则使用系统默认隔离级别它不允许脏读 如果事务级别不设为脏读则 1) T1执行数据库自动加排他锁 2) T2执行数据库发现事务隔离级别不允许脏读便准备为此次select过程加共享锁但发现加不上因为已经有排他锁了所以就 等啊等。直到T1执行完释放了排他锁T2才加上了共享锁然后开始读.... 4 锁的粒度 锁的粒度就是指锁的生效范围就是说是行锁还是页锁还是整表锁. 锁的粒度同样既可以由数据库自动管理也可以通过手工指定hint来管理。 例17 ---------------------------------------- T1: select * from table (paglock) T2: update table set column1hello where id10 T1执行时会先对第一页加锁读完第一页后释放锁再对第二页加锁依此类推。假设前10行记录恰好是一页(当然一般不可能 一页只有10行记录那么T1执行到第一页查询时并不会阻塞T2的更新。 例18 ---------------------------------------- T1: select * from table (rowlock) T2: update table set column1hello where id10 T1执行时对每行加共享锁读取然后释放再对下一行加锁;T2执行时会对id10的那一行试图加锁只要该行没有被T1加上行锁 T2就可以顺利执行update操作。 例19 ---------------------------------------- T1: select * from table (tablock) T2: update table set column1hello where id 10 T1执行对整个表加共享锁. T1必须完全查询完T2才可以允许加锁并开始更新。 以上3例是手工指定锁的粒度也可以通过设定事务隔离级别让数据库自动设置锁的粒度。不同的事务隔离级别数据库会有不同的 加锁策略比如加什么类型的锁加什么粒度的锁。具体请查联机手册。 5 锁与事务隔离级别的优先级 手工指定的锁优先 例20: ---------------------------------------- T1: GO SET TRANSACTION ISOLATION LEVEL SERIALIZABLE GO BEGIN TRANSACTION SELECT * FROM table (NOLOCK) GO T2: update table set column1hello where id10 T1是事物隔离级别为最高级串行锁数据库系统本应对后面的select语句自动加表级锁但因为手工指定了NOLOCK所以该select 语句不会加任何锁所以T2也就不会有任何阻塞。 6 数据库的其它重要Hint以及它们的区别 1) holdlock 对表加共享锁且事务不完成共享锁不释放。 2) tablock 对表加共享锁只要statement不完成共享锁不释放。 与holdlock区别见下例 例21 ---------------------------------------- T1: begin tran select * from table (tablock) T2: begin tran update table set column1hello where id 10 T1执行完select就会释放共享锁然后T2就可以执行update. 此之谓tablock. 下面我们看holdlock 例22 ---------------------------------------- T1: begin tran select * from table (holdlock) T2: begin tran update table set column1hello where id 10 T1执行完select共享锁仍然不会释放仍然会被hold(持有T2也因此必须等待而不能update. 当T1最后执行了commit或 rollback说明这一个事务结束了T2才取得执行权。 3) TABLOCKX 对表加排他锁 例23 ---------------------------------------- T1: select * from table(tablockx) (强行加排他锁 其它session就无法对这个表进行读和更新了除非T1执行完了就会自动释放排他锁。 例24 ---------------------------------------- T1: begin tran select * from table(tablockx) 这次单单select执行完还不行必须整个事务完成执行了commit或rollback后才会释放排他锁。 4) xlock 加排他锁 那它跟tablockx有何区别呢 它可以这样用 例25: ---------------------------------------- select * from table(xlock paglock) 对page加排他锁 而TABLELOCX不能这么用。 xlock还可这么用select * from table(xlock tablock) 效果等同于select * from table(tablockx) 7 锁的超时等待 例26 SET LOCK_TIMEOUT 4000 用来设置锁等待时间单位是毫秒4000意味着等待 4秒可以用select LOCK_TIMEOUT查看当前session的锁超时设置。-1 意味着 永远等待。 T1: begin tran udpate table set column1hello where id 10 T2: set lock_timeout 4000 select * from table wehre id 10 T2执行时会等待T1释放排他锁等了4秒钟如果T1还没有释放排他锁T2就会抛出异常 Lock request time out period exceeded. 8 附各种锁的兼容关系表 | Requested mode | IS | S | U | IX | SIX | X | | Intent shared (IS) | Yes | Yes | Yes | Yes | Yes | No | | Shared (S) | Yes | Yes | Yes | No | No | No | | Update (U) | Yes | Yes | No | No | No | No | | Intent exclusive (IX) | Yes | No | No | Yes | No | No | | Shared with intent exclusive (SIX) | Yes | No | No | No | No | No | | Exclusive (X) | No | No | No | No | No | No | 9 如何提高并发效率 悲观锁利用数据库本身的锁机制实现。通过上面对数据库锁的了解可以根据具体业务情况综合使用事务隔离级别与合理的手工指定锁的方式比如降低锁的粒度等减少并发等待。 乐观锁利用程序处理并发。原理都比较好理解基本一看即懂。方式大概有以下3种 对记录加版本号. 对记录加时间戳. 对将要更新的数据进行提前读取、事后对比。 不论是数据库系统本身的锁机制还是乐观锁这种业务数据级别上的锁机制本质上都是对状态位的读、写、判断。 转载数据库锁 - 口渴的火麒麟 - 博客园
http://www.pierceye.com/news/240969/

相关文章:

  • 建设企业网站的人员组成莱芜网站建设费用
  • 长春建站网站西宁做网站君博专注
  • 学校实验室网站建设现状怎么做网站 ppt
  • 网站建设骗子公司新开传奇网站发布网
  • 智能模板网站建设方案深圳团购网站设计
  • 网站建设和网页设计用wordpress做网站页面显示404
  • 网站首页百度收录怎么做做装修公司网站
  • 湛江网站排名提升免费网站空间有什么用
  • 装修公司网站 源码绍兴市交通建设检测中心网站
  • 企业建设网站流程图珠海网站建设 旭洁
  • 企业商城网站开发互联网行业公司
  • 中国建设人才服务信息网是正规网站wordpress文章分享
  • 渭南网站建设公司电话央美老师做的家具网站
  • 机械网站建设栏目内容怎么欣赏一个网站设计图
  • 帝国cms 网站搬家wordpress 购物 插件下载
  • 怎么做ppt教程网站手机能访问asp网站
  • 电子商务网站建设与管理教材评价织梦网站地图调用全站文章
  • 020网站开发多少钱汕尾建设网站首页
  • 桓台县建设局网站做弹幕网站有哪些
  • 淘宝客导购网站源码iis默认网站属性
  • 做网站用矢量图还是位图安徽省住房和建设厅网站
  • 彭阳网站建设多少钱嘉兴专业的嘉兴专业网站建设项目
  • 网站建设导航分哪几类公司网站大全
  • 网站建设 实训题安能建设总公司网站打不开
  • 莱西网站建设龙岗中心城有学网站建设
  • 重庆技术网站建设宝安做网站哪家好
  • 仿制网站建设写网站建设的软文
  • 0基础网站建设教程wordpress去掉rss订阅
  • 爱网站查询外贸推广具体是做什么
  • 商务网站价格找人做效果图那个网站