多服务器单数据库,如何解决insert数据并发

huangyekan 2014-12-09 10:59:54
问题是这样的,系统是按手机号来下单还款的,一个手机号同一时间只能下一次订单,我们的系统是多点模式的(分布式),那样的话JAVA的并发关键字就不起作用了,要在数据库中做并发控制,请问如何控制?关键点是手机号不能作为唯一键(业务需要)
...全文
547 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
lgmsyy 2014-12-17
  • 打赏
  • 举报
回复
通过队列或者MQ解决吧
tianfang 2014-12-17
  • 打赏
  • 举报
回复
引用 17 楼 shijing266 的回复:
想一个简单的,可不可以弄个时间字段,将时间字段和手机号做个联合唯一
这个也是可行的 ,但是不是时间字段,而是促销活动ID字段+手机号。oracle支持联合唯一
huangyekan 2014-12-17
  • 打赏
  • 举报
回复
引用 17 楼 shijing266 的回复:
想一个简单的,可不可以弄个时间字段,将时间字段和手机号做个联合唯一
这个应该不好做吧,因为唯一字段是ORACLE本身提供的,ORACLE并不能提供联合唯一吧。不知道您有什么好的方法?
AIX_HEAD 2014-12-16
  • 打赏
  • 举报
回复
分布式数据库做离散表吧,可以分为物理分区和逻辑分区,按一定的业务规则进行拆分。 物理分区可以是物理库,也可以是schema 逻辑分区就是不同的表了,即:每个表的结构都一样,tblname不一样。
致知Fighting 2014-12-16
  • 打赏
  • 举报
回复
引用 12 楼 huangyekan 的回复:
[quote=引用 11 楼 ygycomon 的回复:] 为啥会有一个手机号同时下单的情况,是担心重复提交么?
如果他打开2个浏览器同时操作,那是不是就会造成并发的情况。[/quote] 如果是单个用户,是不可能造成并发的
  • 打赏
  • 举报
回复
想一个简单的,可不可以弄个时间字段,将时间字段和手机号做个联合唯一
huangyekan 2014-12-16
  • 打赏
  • 举报
回复
引用 14 楼 AIX_HEAD 的回复:
分布式数据库做离散表吧,可以分为物理分区和逻辑分区,按一定的业务规则进行拆分。 物理分区可以是物理库,也可以是schema 逻辑分区就是不同的表了,即:每个表的结构都一样,tblname不一样。
不是很懂你的意思
huangyekan 2014-12-16
  • 打赏
  • 举报
回复
引用 13 楼 ygycomon 的回复:
[quote=引用 12 楼 huangyekan 的回复:] [quote=引用 11 楼 ygycomon 的回复:] 为啥会有一个手机号同时下单的情况,是担心重复提交么?
如果他打开2个浏览器同时操作,那是不是就会造成并发的情况。[/quote] 如果是单个用户,是不可能造成并发的[/quote] 单个用户也是有可能的,和几个用户无关
致知Fighting 2014-12-15
  • 打赏
  • 举报
回复
为啥会有一个手机号同时下单的情况,是担心重复提交么?
huangyekan 2014-12-15
  • 打赏
  • 举报
回复
引用 8 楼 yutaoaijingjing132 的回复:
你应该有2种解决方式 1:放入一个队列,顺序解决,如果并发不大,应该没有问题 2:使用数据库乐观锁
我知道UPDATE的时候可以用乐观锁,但是INSERT的时候应该无法用乐观锁吧?队列的话,2台机器,很难处理吧
huangyekan 2014-12-15
  • 打赏
  • 举报
回复
引用 11 楼 ygycomon 的回复:
为啥会有一个手机号同时下单的情况,是担心重复提交么?
如果他打开2个浏览器同时操作,那是不是就会造成并发的情况。
yutaoaijingjing132 2014-12-11
  • 打赏
  • 举报
回复
你应该有2种解决方式 1:放入一个队列,顺序解决,如果并发不大,应该没有问题 2:使用数据库乐观锁
huangyekan 2014-12-11
  • 打赏
  • 举报
回复
引用 6 楼 preferme 的回复:
楼主可能没有明白我说的业务逻辑。 1. 先查询不完成交易表里,有没有当前用户的不完整交易,如果没有,进入2. 如果有进入4. 2. 查询历史记录(完整交易表)里,有没有当前用户的完整交易信息,如果没有,进入3. 如果有进入5. 3. 在不完整交易表里面插入记录,手机号码有唯一限定,如果插入失败,诱导用户进入1. 如果插入成功,则进入支付环节,如果支付失败诱导用户进入4. 4. 重复支付操作一次,如果超过重复支付的最大次数,则终止支付 5. 提示用户已经体验过该服务,不能多次使用。
我大致理解你的想法,结合我自己的逻辑业务,我已经能解决这个问题了。 这个问题解决的关键点是加UNIQUE属性的临时表。
muscle1990 2014-12-11
  • 打赏
  • 举报
回复
分布式一致性锁
冰思雨 2014-12-09
  • 打赏
  • 举报
回复
楼主可能没有明白我说的业务逻辑。 1. 先查询不完成交易表里,有没有当前用户的不完整交易,如果没有,进入2. 如果有进入4. 2. 查询历史记录(完整交易表)里,有没有当前用户的完整交易信息,如果没有,进入3. 如果有进入5. 3. 在不完整交易表里面插入记录,手机号码有唯一限定,如果插入失败,诱导用户进入1. 如果插入成功,则进入支付环节,如果支付失败诱导用户进入4. 4. 重复支付操作一次,如果超过重复支付的最大次数,则终止支付 5. 提示用户已经体验过该服务,不能多次使用。
冰思雨 2014-12-09
  • 打赏
  • 举报
回复
临时表里面,对于完整的交易,当然要进行删除操作了,但,这不妨碍你在删除前,先把数据迁移的别的表里面呀。 用户对数据的访问负载,大多在不完整交易的这张表里面,对于完整交易,是不存在插入操作的,只会是查询操作。 那么,针对查询,可以对这个表的数据结构进行优化,提高查询效率。 而不完整交易,则负载较大,插入操作也有,更新操作也有,查询操作也有,所以,要尽量缩短表长度。
huangyekan 2014-12-09
  • 打赏
  • 举报
回复
引用 3 楼 preferme 的回复:
楼主,你搞一个临时表,里面存放不完整交易的信息。当交易完成或者超时未完成时,清除临时表的记录,基本上就OK了。 你所说的并发控制,说白了,也就是不允许临时表里面出现重复的手机号码,那么,手机号码做个唯一约束就可以了。 临时表的长度,要尽量越小越好。如果并发量大,可以采取分表的方式,分担表的负载。这个是后话。
交易完成不能清除记录,唯一能做到的是把失败的记录在状态回写时转移数据。
冰思雨 2014-12-09
  • 打赏
  • 举报
回复
楼主,你搞一个临时表,里面存放不完整交易的信息。当交易完成或者超时未完成时,清除临时表的记录,基本上就OK了。 你所说的并发控制,说白了,也就是不允许临时表里面出现重复的手机号码,那么,手机号码做个唯一约束就可以了。 临时表的长度,要尽量越小越好。如果并发量大,可以采取分表的方式,分担表的负载。这个是后话。
huangyekan 2014-12-09
  • 打赏
  • 举报
回复
引用 1 楼 tianfang 的回复:
需求: 一个手机号同一时间只能下一次订单, 关键点是手机号不能作为唯一键(业务需要); 这两个需求有矛盾或者有表达歧义。 解决方案: 单独建个临时订单表 ,只适用于这段时间;临时表中,一个字段记录手机号,unique属性。抢购结束,批量导入正式订单表
具体业务是这样的。体验还款,也就是输入手机号,获取验证码,然后输入信用卡发卡行和卡号,公司出钱,免费给客户还一笔款。一个手机号只能体验还款一次,如果这个手机号还款结果失败,就能够再体验一次。 如果一个手机号同时开多个浏览器进行还款,那么数据落订单的时候肯定会发生并发问题。 按照你说的临时表,我觉得也有可行性,也就是先把订单落入临时表,这样能够防止并发。然后把还款状态为失败的数据导入正式表。但是这之中会有一个问题,数据需要实时同步,这样会不会造成系统开销过大。还有同步的过程中肯定有时间差,比如临时表中数据还在,但是用户已经得知还款失败可以再还一笔了,于是用户再去还款的时候,造成还款订单下不了。
tianfang 2014-12-09
  • 打赏
  • 举报
回复
需求: 一个手机号同一时间只能下一次订单, 关键点是手机号不能作为唯一键(业务需要); 这两个需求有矛盾或者有表达歧义。 解决方案: 单独建个临时订单表 ,只适用于这段时间;临时表中,一个字段记录手机号,unique属性。抢购结束,批量导入正式订单表

67,513

社区成员

发帖
与我相关
我的任务
社区描述
J2EE只是Java企业应用。我们需要一个跨J2SE/WEB/EJB的微容器,保护我们的业务核心组件(中间件),以延续它的生命力,而不是依赖J2SE/J2EE版本。
社区管理员
  • Java EE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧