`
zorufa876
  • 浏览: 82740 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
文章分类
社区版块
存档分类
最新评论

并发的时候,控制插入的数据只有一条的方案总结

SQL 
阅读更多

 

   最近在做一个项目,碰到一个需要处理并发的问题,情况是这样的

   现在有一张优惠券表,里面放的是一张张优惠券的信息,有这么几个字段,包括

   id(优惠券id),

   sellerId(卖家id),

   buyerId(买家id),

   get_condition(领取条件,就是买家在领取这张优惠群需要的条件,包括“免费领取”,“积分兑换”)

   当然还有其他字段,这里就不列出了。

 

   当一个买家在页面上点击一个卖家发放的优惠券的时候,就会在这个表中插入一条优惠券信息

   好,现在有这样的需求,就是保证每个买家在一个卖家那里免费领取的优惠券最多只能有一张,由于存在并发的可能,所以想了以下几种方案。

 

   方案一:在buyerId,sellerId和get_condition这三个字段上建唯一性索引:

   问题:由于get_condition这个字段是有两种信息的,包括“免费领取”和“积分兑换”,每个买家免费领取的优惠券虽然只能有一张,但是积分兑换的优惠券却是可以领n张的。所以这个唯一性索引建不起来。

 

   方案二:用如下的sql语句:

 

insert into t1

  (id, buyerId, sellerId, get_condition)

  select seq_seller_id.nextval, 111, 100, '免费领取'

    from (select * from user_tab_columns where rownum = 1) t

   where (select count(*)

            from t1

           where buyerId = 111

             and sellerId = 100

             and get_condition = '免费领取') < 1

 

    问题:如果现在的需求是只需要插入优惠券表的话,那么这条sql是可以解决问题的,但是在插入优惠券表的时候,我还需要维护其他的几张表,而为了保证数据的一致性,就必须在维护这几个表的时候开事务,由于事务的原因,这条sql语句的执行结果只有在事务的最后才会提交的数据库,所以一旦并发,还是没有办法保证每个买家在一个卖家哪里免费领取的优惠券只能有一张。

 

   方案三:分字段,就是把get_condition字段分成两个字段,分别记录了免费领取的数据和积分兑换的数据。然后在buyerId,sellerId,和记录免费领取数据的字段上面建唯一性索引。

   问题:这样虽然可以解决问题,但是同样业务意义的数据分成两个字段总感觉可维护性不太好。而且如果需求方说改需求了,说每个买家在一个卖家那里免费领取的优惠券可以有多张了,那这个分出来的字段就没啥意义了,而且更悲剧的是,过几天需求方又说要改回来,从多张变为一张,那怎么建唯一性索引?

 

   方案四:分表,就是再建一个表,里面冗余了优惠券表的id,buyerId,sellerId,get_condition这四个字段,放的只是领取条件为免费领取的优惠券的记录。

   问题:这样虽然可以解决目前的问题,但是跟上面那种方案同样的问题,我们需要考虑以后的情况,就是说以后如果从一张变成n张乐,那我们这张分出来的表就没有存在的意义了。而过几天又从多张又变回一张了,那唯一性索引又怎么建?在这种情况下,我们可以在这个表中再加一个记录优惠券数量的新字段,比如叫num。现在需求方说只能有一张,就在buyerId,sellerId,get_condition这三个字段上建唯一性索引,到时候如果需求改动了,从一张改为n张,那么就要多维护一个num字段,同样buyerId,sellerId,get_condition的数据插入的时候,只需改动num就行了。如果需求又改回来,从n张变一张,那么,只需要放弃维护num字段就行了。而这种建num字段的方法在第三种方案中也是适用的。

 

   总体感觉这几种方案都不是很好,况且如果利用数据库来控制并发的插入数据,总感觉成本太大,有谁有更好的办法吗?

 

 

 

 

 

分享到:
评论

相关推荐

    Sqlserver大数据量插入速度慢或丢失数据的解决方法

    1. **并发控制不当**:多线程或多个进程同时插入数据时,如果没有适当的并发控制机制,可能会导致数据丢失。 2. **事务管理问题**:如果在事务未提交的情况下就发生异常或者中断,则可能导致部分数据未能成功写入...

    Sqlite数据库里插入数据的条数上限是500

    今天在向Sqlite数据库里插入数据的时候,报了这样一个错: 代码如下: “too many terms in compound SELECT” 去Stackoverflow上查了一下,发现有人回答这个问题:链接 原来一次性向数据库里插入数据的条数不能太...

    数据库并发控制

    - **封锁(Locking)**:这是一种最基本的并发控制技术,通过锁定数据对象来阻止其他事务对其进行修改。主要有两种类型的锁: - **排它锁(X锁)**:一旦事务对数据加了X锁,其他事务就无法再对该数据加任何类型的...

    阿里巴巴大并发插入优化案例

    标题和描述均提到了“阿里巴巴大并发插入优化案例”,这主要聚焦于阿里巴巴在处理大规模并发数据插入场景下所采取的一系列优化措施和技术实践。本文将深入解析阿里巴巴B2B团队首席DBA吕海波(VAGE)分享的优化案例,...

    PowerBuilder_SQL Server结构下的并发控制.pdf

    最后,KeyandModifedColumns参数则是在KeyColumns和KeyandUpdateableColumns的基础上的折衷方案,它提供了对数据完整性和并发操作数量之间的平衡控制。 另一方面,SQL Server的并发控制是通过事务的封锁机制来实现...

    并发的事务中保证数据表数据完整性的一些思考.docx

    例如,`select row_id into v_max from table_name where rownum = 1 order by row_id desc for update`,这个查询旨在倒序排序后选取第一条记录并锁定。虽然这种方法在一定程度上避免了并发问题,但`rownum`并不...

    Sqlserver 高并发和大数据存储方案

    【Sqlserver 高并发和大数据存储方案】 在面临高并发和大数据存储的挑战时,Sqlserver 提供了一系列的策略和优化方法。以下是一些关键点的详细解释: 1. **解决高并发问题**: - **异步处理**:面对大量并发写...

    MySQL Innodb锁解决并发问题

    4. **更新当前发放数量**:在事务中增加`coup_num_current`,并尝试插入一条新的优惠券发放记录。 5. **提交或回滚**:如果更新成功,则提交事务;否则,回滚事务。 这种方法通过在更新数据时检查数据是否发生变化...

    高并发系统数据幂等的解决方案

    6. **插入数据的唯一索引**: 在数据库表上设置唯一索引可以确保特定业务场景下数据的唯一性,防止重复插入。例如,通过业务主键作为唯一标识,确保每条记录的唯一性。 7. **API层面的幂等性**: 对于API接口,...

    针对Sqlserver大数据量插入速度慢或丢失数据的解决方法

    并发插入可能导致数据丢失,通常是因为并发控制机制(如锁)导致的冲突。确保使用适当的事务隔离级别,并合理控制事务大小,避免长时间持有锁。 5. **批量更新和删除**: 如果在插入新数据的同时需要更新或删除旧...

    Mysql事务并发问题解决方案

    插入操作也类似,只能成功插入一条数据,因为其他插入请求在检查时发现已有相同数据存在。 面对这些挑战,还可以考虑其他策略,如使用自增序列、行级锁定、MVCC(多版本并发控制)等。例如,MySQL的InnoDB引擎支持...

    浅谈高并发下接口幂等性解决方案.docx

    7. 分布式锁如果是分布是系统,构建全局唯一索引比较困难,例如唯一性的字段没法确定,这时候可以引入分布式锁,通过第三方的系统(redis 或 zookeeper),在业务系统插入数据或者更新数据,获取分布式锁,然后做操作...

    基于Kettle工具的企业级数据同步方案

    2. 对于数据更新不丢失,可以采用循环分页插入,并在最后一条数据处理后记录其update_time,作为下次同步的起点。 3. 为处理更新冲突,可以在update_time基础上设定一个缓冲时间,避免因延迟而导致的数据丢失。 ...

    数据库并发一致性案例分析

    总结来说,数据库并发一致性案例分析深入探讨了并发控制的重要性,并通过具体案例,揭示了不同事务隔离级别在实际应用中可能遇到的问题及其解决方案。通过分析和实践,可以加深对SQL语言和数据库事务管理的理解,...

    mysql百万级测试数据下载 300W条

    首先,`test.sql`文件是一个MySQL数据库的SQL脚本文件,通常包含创建表结构、插入数据等操作。在这个场景中,它包含了300万条记录,这对于测试数据库性能、查询优化、并发处理能力等提供了充足的数据基础。 1. **...

    300万条mysql测试数据

    6. **并发性能**:当多个用户同时访问和操作数据库时,测试数据有助于检测系统的并发处理能力,如锁等待、死锁等问题,以及调整并发控制策略。 7. **数据导入导出**:对于大型数据集,批量导入和导出性能也很关键。...

    java实现csv导出千万级数据实例

    本实例聚焦于“java实现csv导出千万级数据实例”,旨在提供一个高效、稳定的解决方案,避免因数据量过大而导致的性能问题,如Java中的栈溢出(Stack Overflow)。CSV(Comma Separated Values)格式因其简单、通用性...

    完美解决Thinkphp3.2中插入相同数据的问题

    本文将详细探讨如何在ThinkPHP 3.2版本中处理插入重复数据的问题,以及MySQL中的两种解决方案——`ON DUPLICATE KEY UPDATE` 和 `REPLACE INTO`。 首先,我们需要理解问题背景。在使用ThinkPHP 3.2进行数据插入时,...

    Hibernate中大量数据的更新

    在这些场景中,如果使用传统的 INSERT 语句逐条插入数据,会导致性能下降和内存溢出问题。因此,使用批量更新机制可以大大提高性能和降低内存占用。 Hibernate 的批量更新机制 Hibernate 提供了两种批量更新机制:...

    Sql批量操作数据

    1. **技术方案一:** 使用数据库访问类调用存储过程,通过循环逐条插入数据。这是一种最直接但效率较低的方法。 2. **技术方案二:** 利用ADO.NET中的`SqlBulkCopy`特性。该方法能够显著提高批量数据的插入速度。 ...

Global site tag (gtag.js) - Google Analytics