加一张防重表,在防重表中增加商品表的name和model字段作为唯一索引。
例如:
CREATE TABLE `product_unique` ( `id` bigint(20) NOT NULL COMMENT 'id', `name` varchar(130) DEFAULT NULL COMMENT '名称', `model` varchar(255) NOT NULL COMMENT '规格', `user_id` bigint(20) unsigned NOT NULL COMMENT '创建用户id', `user_name` varchar(30) NOT NULL COMMENT '创建用户名称', `create_date` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间', PRIMARY KEY (`id`), UNIQUE KEY `ux_name_model` (`name`,`model`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='商品防重表';
其中表中的id可以用商品表的id,表中的name和model就是商品表的name和model,不过在这张防重表中增加了这两个字段的唯一索引。
视野一下子被打开了。
在添加商品数据之前,先添加防重表。如果添加成功,则说明可以正常添加商品,如果添加失败,则说明有重复数据。
防重表添加失败,后续的业务处理,要根据实际业务需求而定。
如果业务上允许添加一批商品时,发现有重复的,直接抛异常,则可以提示用户:系统检测到重复的商品,请刷新页面重试。
例如:
try { transactionTemplate.execute((status) -> { productUniqueMapper.batchInsert(productUniqueList); productMapper.batchInsert(productList); return Boolean.TRUE; }); } catch(DuplicateKeyException e) { throw new BusinessException("系统检测到重复的商品,请刷新页面重试"); }
在批量插入数据时,如果出现了重复数据,捕获DuplicateKeyException异常,转换成BusinessException这样运行时的业务异常。
还有一种业务场景,要求即使出现了重复的商品,也不抛异常,让业务流程也能够正常走下去。
例如:
try { transactionTemplate.execute((status) -> { productUniqueMapper.insert(productUnique); productMapper.insert(product); return Boolean.TRUE; }); } catch(DuplicateKeyException e) { product = productMapper.query(product); }
在插入数据时,如果出现了重复数据,则捕获DuplicateKeyException,在catch代码块中再查询一次商品数据,将数据库已有的商品直接返回。
如果调用了同步添加商品的接口,这里非常关键的一点,是要返回已有数据的id,业务系统做后续操作,要拿这个id操作。
当然在执行execute之前,还是需要先查一下商品数据是否存在,如果已经存在,则直接返回已有数据,如果不存在,才执行execute方法。这一步千万不能少。
例如:
Product oldProduct = productMapper.query(product); if(Objects.nonNull(oldProduct)) { return oldProduct; } try { transactionTemplate.execute((status) -> { productUniqueMapper.insert(productUnique); productMapper.insert(product); return Boolean.TRUE; }); } catch(DuplicateKeyException e) { product = productMapper.query(product); } return product;
千万注意:防重表和添加商品的操作必须要在同一个事务中,否则会出问题。
顺便说一下,还需要对商品的删除功能做特殊处理一下,在逻辑删除商品表的同时,要物理删除防重表。用商品表id作为查询条件即可。
标签:COMMENT,product,java,name,商品,提交,防重表,id From: https://www.cnblogs.com/privateLogs/p/17534998.html