java分布式并发唯一键冲突解决总结
2012-12-02 16:56
337 查看
在单台web服务器情况下,我们处理并发的时候,可以用到关键字sychronized或相关并发类库即可方便处理。
一旦遇到多台web服务器情况下,也就是分布式并发下,采用上述处理方式是不行的,因为存在多个jvm,以上方法就失效了。
下面让我们考虑一个这样一个场景:
业务背景:举办一场讲座,采取网上抢票分号码的行,号码不能重复,及讲座id与号码形成一个唯一键,如course表:id,seatNum,其他字段等等
环境:多台web服务器提供服务
要保证上述业务正常运行,可能会碰到并发情况,多个人抢到的号码一样,这样存入db时候,会抛出异常,因为设置了唯一键,不允许号码重复。那有什么方法能很好解决呢?
可以采用对表加锁方式,采用悲观锁能很好解决这个问题,但是效率不高,还可能出现死锁。采用乐观锁,也就是用程序实现时候发现抛出异常,就继续处理,这种方式较暴力,也没很好解决这个问题。
额外加一张表course_extra,seatNum作为自增主键,course_id等,每次分号码,直接往这个插入一条数据,这样保证每次seatNum自增,不会出现重复。
要是有多场讲座,并且每场讲座的号码都从1开始呢?采用额外表的时候,是不是每场讲座都需要额外建一张表呢?这也太浪费数据库空间了吧。
这样的话,可以建另外一张表course_sequence:id, current_val, increment,每次取的时候,都获取current_val的值,并且采用自建函数如next_val或存储过程,每次获取当前值的时候,自动获取下一个值更新当前值,类似事务处理方式,不能拆开执行。否则,也有并发情况存在,导致重复。
采用分布式缓存memcache,采用自带的原子递增方式,能很好解决这个问题。为了防止缓存失效等问题,需要定时读、写数据库,保证号码是最大的,否则缓存一旦失效,也会面临类似并发问题。注意:原子递增时候,都需要采用string类型,int也需要转string才行。
总结,最后在实际应用中,考虑到各种问题的存在,采用了memcache来解决。
一旦遇到多台web服务器情况下,也就是分布式并发下,采用上述处理方式是不行的,因为存在多个jvm,以上方法就失效了。
下面让我们考虑一个这样一个场景:
业务背景:举办一场讲座,采取网上抢票分号码的行,号码不能重复,及讲座id与号码形成一个唯一键,如course表:id,seatNum,其他字段等等
环境:多台web服务器提供服务
要保证上述业务正常运行,可能会碰到并发情况,多个人抢到的号码一样,这样存入db时候,会抛出异常,因为设置了唯一键,不允许号码重复。那有什么方法能很好解决呢?
可以采用对表加锁方式,采用悲观锁能很好解决这个问题,但是效率不高,还可能出现死锁。采用乐观锁,也就是用程序实现时候发现抛出异常,就继续处理,这种方式较暴力,也没很好解决这个问题。
额外加一张表course_extra,seatNum作为自增主键,course_id等,每次分号码,直接往这个插入一条数据,这样保证每次seatNum自增,不会出现重复。
要是有多场讲座,并且每场讲座的号码都从1开始呢?采用额外表的时候,是不是每场讲座都需要额外建一张表呢?这也太浪费数据库空间了吧。
这样的话,可以建另外一张表course_sequence:id, current_val, increment,每次取的时候,都获取current_val的值,并且采用自建函数如next_val或存储过程,每次获取当前值的时候,自动获取下一个值更新当前值,类似事务处理方式,不能拆开执行。否则,也有并发情况存在,导致重复。
采用分布式缓存memcache,采用自带的原子递增方式,能很好解决这个问题。为了防止缓存失效等问题,需要定时读、写数据库,保证号码是最大的,否则缓存一旦失效,也会面临类似并发问题。注意:原子递增时候,都需要采用string类型,int也需要转string才行。
总结,最后在实际应用中,考虑到各种问题的存在,采用了memcache来解决。
相关文章推荐
- java-高并发-高并发分布式系统中生成全局唯一Id汇总
- java 解决分布式环境中 高并发环境下数据插入重复问题
- JAVA日志依赖冲突解决总结
- Java异常解决总结001-org.apache.jasper.JasperException: java.lang.IllegalStateException: No output fold
- 10 Java并发编程1总结
- 企业级JAVA大型分布式电商项目实战高并发集群分布式系统架构视频教程下载
- JAVA多线程与并发学习总结
- Java高并发,如何解决,什么方式解决
- java并发 分布式锁
- MyBatis学习总结_04_解决字段名与实体类属性名不相同的冲突
- Java架构师攻城狮之路:大数据,分布式,hadoop,java,高并发系统设计,高端培训视频,全栈开通
- Java并发-ConcurrentModificationException原因源码分析与解决办法
- Gradle依赖项学习总结,dependencies、transitive、force、exclude的使用与依赖冲突解决
- java并发基础总结
- 个人知识点总结——Java并发
- Java并发、同步总结
- JAVA中常用的高级集合类总结(包含Concurrent包下的并发集合类)
- javamail,java发email,发邮件,jaf,activation,j2ee5冲突问题解决
- java大型分布式电商项目实战高并发集群分布式系统架构
- MyBatis由浅入深学习总结之二:MyBatis解决Java实体类和数据库表字段不一致方法总结