关于并发的问题

问题描述

请教各位大神,对于从数据库查询一些数据,然后根据这些数据进行判断,判断通过再做数据插入或更新操作。那如果两个页面同时提交请求,就有可能存在数据判断时,这两个请求都是符合要求的,但是当最终数据更新到数据库中之后,数据就可能存在问题了。像这种情况一般是通过什么办法解决的?

解决方案

解决方案二:
传统上,数据库采用事务的方式来保持会话同步,来达到数据一致性。在你使用ado.net编程时,通过显式使用DbTransanction来将多个程序语句放到一个“数据库实务操作”范围内来处理。数据库系统默认的事务隔离级别,一般来说都是在一个事务中自动去禁止其它事务读取本事务已经访问过的记录,以此避免脏读、幻象读。这是传统上的做法。不过最近几年随着大规模电商的兴起,特别是互联网大型公司“去IOE潮流”的兴起,传统数据库做法被逐渐诟病了。例如用很低档次的电脑组成的服务器集群,例如用20万的投资,可以做硬软件投资200万的专用服务器和数据库系统的业务处理操作,而且速度还能提高几十倍。因此,实际上现在时兴的做法是用程序员的智慧、自己设计高效率的业务数据同步算法,来尽量避免滥用数据库事务加锁。甚至现在许多地方都讲究“最终一致性”而不是“数据库事务”。
解决方案三:
你的问题比较宽泛而没有具体业务应用场景,我也就随便举几个简单的例子来说。比如说有人说要什么“各个终端的业务流水号都是连续的”。你看到淘宝上的订单的流水号全都是连续的吗?这一个不科学的所谓空想,程序员自认为“真的好高大上啊”的想法,就会把淘宝网整垮!因此从业务分析上设计,去掉不合理的所谓约束,那“计算机脑袋”重新改为更合理的“业务的脑袋”这是第一步。一个服务器上的订单流水号是可以在进程内使用lock方式来同步的(而且也只是为订单号+1的操作进行lock,处理订单部分并不lock),于是订单就可以是“服务器编号+流水号”这样的形式。于是你看到,订单号至少是根据每一个服务器编号,而散列开的。并不是什么“大流水号”。更进一步地,许多关键业务id号连这个lock也觉得是个垃圾、可以去掉,于是可能是“随机号+服务器编号+当前时间”的组合这个算法来产生id号。目的就是尽量不要纠结什么“并发时同步”的问题。再比如说,假设我们要购火车票,那么一个终端在确定要两张票之后,这两张票瞬间就被从“待售”的库存里转到“正在售”的库存里了。这样就避免了数据库事务中不小心把这些没有用的数据行也上锁。这样就回避了事务(而不是像有些程序员那样,非要用技术才显得高大上)。再比如说,假设1000人在0.1秒钟内抢走任务去做,那么先把这些任务放到一个高速缓存或者一个简单的soa服务上去就行了。至于说每一个人抢到任务编号之后,再去后台真正地获取任务内容、执行任务,这整个冗长的过程,根本不加锁。而有些程序可能就会纠结于1000人执行任务时“并发”问题而头疼不已。总之,没有技术而能够解决问题,是最好的技术。其次就是现在比较流行分布式处理方式,避免加锁。
解决方案四:
把这个判断与写入放到一个事务里,这两步就是一起的操作,但是还是要有关系才行,比如判断有了就不写入了,那么第二个请求不可能写入。一般我们只对关系的地方做这种事务的处理,比如金额,库存等操作,普通的操作,如果出现了可以手动处理,一般这种出现很小,因为事务对性能会有一定的损耗。

时间: 2024-10-31 07:02:46

关于并发的问题的相关文章

并发集合(三)使用阻塞线程安全的列表

使用阻塞线程安全的列表 列表(list)是最基本的集合.一个列表中的元素数量是不确定的,并且你可以添加.读取和删除任意位置上的元素.并发列表允许不同的线程在同一时刻对列表里的元素进行添加或删除,而不会产生任何数据不一致的问题. 在这个指南中,你将学习如何在你的并发应用程序中使用阻塞的列表.阻塞列表与非阻塞列表的主要区别是,阻塞列表有添加和删除元素的方法,如果由于列表已满或为空而导致这些操作不能立即进行,它们将阻塞调用的线程,直到这些操作可以进行.Java包含实现阻塞列表的LinkedBlocki

nginx中如何限制下载和并发速度

1.添加limit_zone(这个变量只能在http协议使用) 2.编辑nginx.conf文件 向其中添加limit_zone one $remote_addr 10m指令,然后添加limit_conn,由于这个变量在http.server.location段使用,而且只限制一个站点,所以添加到server里面即可 http://wiki.nginx.org/NginxHttpLimitZoneModule 下载limit_zone http://wiki.nginx.org/NginxHtt

Java并发中正确使用volatile

作者:一粟   整理和翻译自Twitter实时搜索的PPT 前几天并发编程群里有同学对volatile的用法提出了疑问,刚好我记得Twitter有关实时搜索的这个PPT对这个问题解释的很清晰并有一个实际的应用场景,于是周末把这个问题摘录了一些和并发相关的内容如下: 并发 – 定义 悲观锁 – Pressimistic locking 一个线性在执行一个操作时持有对一个资源的独占锁.(互斥) 一般用在冲突比较可能发生的场景下 乐观锁 – Optimistic locking 尝试采用原子操作,而不

如何实现高容量大并发数据库服务 | 数据库分布式架构设计

袋鼠学院和优云.阿里云联合举办的沙龙结束之后,总是有小伙伴们来问PPT内容,想要进一步了解Topic内容.(哦,对了对了,竟然还有小伙伴专门冲着袋鼠云去听沙龙,感动cry~~) 千呼万唤,忙成狗的袋鼠小妹终于把沙龙总结整理了出来(⊙o⊙) 本次沙龙的主题是"云时代下的运维管理实践",受邀请的演讲嘉宾,花名宏翊(经常关注袋鼠云的同学,肯定已经对这个名字很熟悉了),是袋鼠云首席数据库架构师,袋鼠学院数据库讲师. 呼应沙龙运维实践的主题,结合自己的专长领域,宏翊主要是从数据库领域来谈云时代下

#运维侠客行·杭州站# 如何实现高容量大并发数据库服务

运维侠客行杭州站·讲师 宏翊,袋鼠云首席架构师,袋鼠学院数据库讲师. 在2017运维侠客行·杭州站上,主办方优云软件特意邀请了来自袋鼠云的首席数据库架构师宏翊给大家带来了如何实现高容量大并发数据库服务.为什么数据库需要做分布式架构设计?在对数据库进行拆分设计和实施时,会遇到哪些坑?又该如何避免踩坑?一起来了解下吧. ▍摘要 数据库拆分要根据业务现状.模式,选择合适的拆分方式,紧密结合业务及应用架构设计,谨慎拆分,防止过度设计. ▍正文 一 为什么要做分布式数据库架构改造? 云计算大数据时代,传统

你真的了解:IIS连接数、IIS并发连接数、IIS最大并发工作线程数、应用程序池的队列长度、应用程序池的最大工作进程数 吗?

原文:你真的了解:IIS连接数.IIS并发连接数.IIS最大并发工作线程数.应用程序池的队列长度.应用程序池的最大工作进程数 吗? IIS连接数   一般购买过虚拟主机的朋友都熟悉购买时,会限制IIS连接数,这边先从普通不懂代码用户角度理解IIS连接数 顾名思义即为IIS服务器可以同时容纳客户请求的最高连接数,准确的说应该叫"IIS限制连接数" 这边客户请求的连接内容包括: 1.网站html请求,html中的图片资源,html中的脚本资源,其他需要连接下载的资源等等,任何一个资源的请求

并发编程语言 Clojure 1.5 正式版发布

Clojure 终于迎来了 1.5 正式版本,该版本要求 Java 6 或者更新的版本.该版本包含一些新特性.性能方面改进,错误提示的改进,文档完善等等,详情请看发行说明. Clojure是一种LISP风格的语言,运行在JVM上.Clojure的一大特色就是其并发机制,它支持不可变的数据结构(Clojure是来自于可持久化的数据结构).Clojure还有一个特色是软件事务存储(Software Transactional Memory,STM),其支持用事务代替锁和互斥器来更新共享内存.STM还

如何解决高并发的抢购问题

问题描述 如何解决高并发的抢购问题 前几天去南京付融宝面试,提了这样一个问题:在某天的上午10点有这样一个抢购活动,抢购的商品数量1000,初步估计那个时间点抢购的人数在100万左右,如何处理这样的一个问题. 解决方案 首先,你要有足够的服务器,保持前端页面能够正常调用.你可以用内容分发网络(cdn)使得前端应用层可以工作.然后,你可以产生一个随机数,以大约0.01的概率从前端服务器将订购请求发送到你的业务层,其余直接返回售罄.此时你的业务层已经只有1万的并发了,用事务队列保证抢购和存货的匹配.

从JVM并发看CPU内存指令重排序(Memory Reordering)

这两天,我拜读了 Dennis Byrne 写的一片博文Memory Barriers and JVM Concurrency (中译文内存屏障与JVM并发). 文中提到: 对主存的一次访问一般花费硬件的数百次时钟周期.处理器通过缓存(caching)能够从数量级上降低内存延迟的成本这些缓存为了性能重新排列待定内存操作的顺序.也就是说,程序的读写操作不一定会按照它要求处理器的顺序执行. 这段话是作者对内存屏障重要性的定义.通过cache降低内存延迟,这句话很好理解.但后面那句"为了性能重排序内存

并发集合(五)使用线程安全的、带有延迟元素的列表

使用线程安全的.带有延迟元素的列表 DelayedQueue类是Java API提供的一种有趣的数据结构,并且你可以用在并发应用程序中.在这个类中,你可以存储带有激活日期的元素.方法返回或抽取队列的元素将忽略未到期的数据元素.它们对这些方法来说是看不见的. 为了获取这种行为,你想要存储到DelayedQueue类中的元素必须实现Delayed接口.这个接口允许你处理延迟对象,所以你将实现存储在DelayedQueue对象的激活日期,这个激活时期将作为对象的剩余时间,直到激活日期到来.这个接口强制