Reference: http://blog.ruaby.com/?p=256html
相对于串行处理来讲,并发事务处理能大大增长数据库资源的利用率,提升数据库系统的事务吞吐量,从而能够支持更多的用户。但并发事务处理也会带来一些问题,主要包括如下几种状况:mysql
在上面讲到的并发事务处理带来的问题中,“更新丢失”一般是应该彻底避免的。但防止更新丢失,并不能单靠数据库事务控制器来解决,须要应用程序对要更新的数据加必要的锁来解决,所以,防止更新丢失应该是应用的责任。git
“脏读”、“不可重复读”和“幻读”,其实都是数据库读一致性问题,必须由数据库提供必定的事务隔离机制来解决。数据库实现事务隔离的方式,基本上可分为如下两种:github
数据库的事务隔离越严格,并发反作用越小,但付出的代价也就越大,由于事务隔离实质上就是使事务在必定程度上 “串行化”进行,这显然与“并发”是矛盾的。同时,不一样的应用对读一致性和事务隔离程度的要求也是不一样的,好比许多应用对“不可重复读”和“幻读”并不敏感,可能更关心数据并发访问的能力。sql
InnoDB实现了如下两种类型的行锁。数据库
对于UPDATE、DELETE和INSERT语句,InnoDB会自动给涉及数据集加排他锁(X);对于普通SELECT语句,InnoDB不会加任何锁;事务能够经过如下语句显示给记录集加共享锁或排他锁。并发
用SELECT … IN SHARE MODE得到共享锁,主要用在须要数据依存关系时来确认某行记录是否存在,并确保没有人对这个记录进行UPDATE或者DELETE操做。可是若是当前事务也须要对该记录进行更新操做,则颇有可能形成死锁,对于锁定行记录后须要进行更新操做的应用,应该使用SELECT… FOR UPDATE方式得到排他锁。htm
更多详情参考:http://www.cnblogs.com/qq78292959/archive/2013/01/30/2883100.htmlblog
github项目地址:https://github.com/sanjiOP/seckill事务
按照正常的购买流程:查询商品库存,库存大于0时,生成订单,去库存。若是出现并发,致使在查询商品库存的时候,库存会一直出现大于0的状况,出现超卖现象。
基于mysql的事务和锁实现方式:
若是不开启事务,第二步即便加锁,第一个会话读库存结束后,变会释放锁,第二个会话仍有机会在去库存前读库存,出现超卖。
若是开启事务,第二步不加锁,第一个会话读库存结束后,第二个会话容易出现【脏读】,出现超卖。
即加事务,又加读锁:开启事务,第一个会话读库存时加读锁,并发时,第二个会话也容许得到读库存的读锁,可是在第一个会话执行写操做时,写锁便会等待第二个会话的读锁,第二个会话执行写操做时,写锁便会等待第一个会话的读锁,出现死锁
即加事务,又加写锁:第一个会话读库存时加写锁,写锁会阻止其它事务的读锁和写锁。直到commit才会释放,容许第二个会话查询库存,不会出现超卖现象。