设为首页 加入收藏

TOP

浅析项目中的并发 ( 一 )(二)
2017-11-10 08:32:56 】 浏览:534
Tags:浅析 项目 并发
,此时,商品数据表现为一个共享数据,所以存在微弱的并发,通常表现为数据的脏读,例如操作员A,B同时对一个商品信息维护,我们希望只能有一个操作员修改成功,另外一个操作员得到错误提示(该商品信息已经发生变化),否则,两个人都以为自己修改成功了,但是其实只有一个人完成了操作,另一个人的操作被覆盖了。

这个场景表现为:存在并发,需要控制,允许失败,场景乐观。

通常我建议这种场景使用乐观锁,即在商品属性添加一个version字段标记修改的版本,这样两个操作员拿到同一个版本号,第一个操作员修改成功后版本号变化,另一个操作员的修改就会失败了。

class Goods{
	@Version
	int version;
}
//Transaction start
try{
	Goods goods = goodsDao.findById("1");
	goods.setName("newName");
	goods.setPrice(goods.getPrice()+100.00);
	...//其他耗时操作
	goodsDao.save(goods);
}catch(org.hibernate.StaleObjectStateException e){
	//返回给前台
}
//Transaction commit

springdata配合jpa可以自动捕获version异常,也可以自动手动对比。

第三个场景
这个场景表现为:存在频繁的并发,需要控制,不允许失败,场景悲观。

强调一下,本例不应该使用在项目中,只是为了举例而设置的一个场景,因为这种贫血模型无法满足复杂的业务场景,而且依靠单机事务来保证一致性,并发性能和可扩展性能不好。

一个简易的秒杀场景,大量请求在短时间涌入,是不可能像第二种场景一样,100个并发请求,一个成功,其他99个全部异常的。

设计方案应该达到的效果是:有足够库存时,允许并发,库存到0时,之后的请求全部失败;有足够金额时,允许并发,金额不够支付时立刻告知余额不足。

可以利用数据库的行级锁,
update set balance = balance – money where userId = ? and balance >= money;
update stock = stock – number where goodsId = ? and stock >= number ; 然后在后台 查看返回值是否影响行数为1,判断请求是否成功,利用数据库保证并发。

需要补充一点,我这里所讲的秒杀,并不是指双11那种级别的秒杀,那需要多层架构去控制并发,前端拦截,负载均衡….不能仅仅依赖于数据库的,会导致严重的性能问题。为了留一下一个直观的感受,这里对比一下oracle,mysql的两个主流存储引擎:innodb,myisam的性能问题。

oracle:
10000个线程共计1000000次并发请求:共花费:101017 ms =>101s
innodb:
10000个线程共计1000000次并发请求:共花费:550330 ms =>550s
myisam:
10000个线程共计1000000次并发请求:共花费:75802 ms =>75s

可见,如果真正有大量请求到达数据库,光是依靠数据库解决并发是不现实的,所以仅仅只用数据库来做保障而不是完全依赖。需要根据业务场景选择合适的控制并发手段。

首页 上一页 1 2 下一页 尾页 2/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇编辑 java 逃逸分析 下一篇就是让你懂 Spring 中 Mybatis 的..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目