知行合一|

hiwwwk

园龄:5年1个月粉丝:4关注:12

2022-02-14 20:48阅读: 372评论: 0推荐: 0

.NetCore利用Redis简单封装生成顺序号

前言

有不少业务场景下需要生成流水号,比较简单的情况是新建一个表,然后利用自增Id来实现。但这种实现弊端比较大,占用数据库资源,操作步骤也多。于是想到使用Redis更好,因为是基于内存操作的,速度快且具有原子性。

实现

新建项目RedisDemo
image.png
image.png
新建接口ISequenceNumberGenerator

using System.Threading.Tasks;

namespace RedisDemo
{
    public interface ISequenceNumberGenerator
    {
        Task<long> GenerateAsync(string key);

        Task<string> GenerateAsync(string key, int totalWidth);
    }
}

通过Nuget引入类库StackExchange.Redis
新建实现类SequenceNumberGenerator

using Microsoft.Extensions.Configuration;
using StackExchange.Redis;
using System.Threading.Tasks;

namespace RedisDemo
{
    public class SequenceNumberGenerator : ISequenceNumberGenerator
    {
        protected ConnectionMultiplexer RedisConnection { get; }

        public SequenceNumberGenerator(IConfiguration configuration)
        {
            RedisConnection = ConnectionMultiplexer.Connect(configuration["Redis:Configuration"]);
        }

        protected virtual IDatabase GetDatabase()
        {
            return RedisConnection.GetDatabase();
        }

        public async Task<long> GenerateAsync(string key)
        {
            var db = GetDatabase();

            return await db.StringIncrementAsync(key);
        }

        public async Task<string> GenerateAsync(string key, int totalWidth)
        {
            var incrementValue = await GenerateAsync(key);

            return incrementValue.ToString().PadLeft(totalWidth, '0');
        }
    }
}

代码写完开始测试
新建xunit测试项目
image.png
将自带的类文件重命名为SequenceNumberGenerator_Test

using Microsoft.Extensions.Configuration;
using RedisDemo;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Xunit;
using Xunit.Abstractions;

namespace RedisDemoTest
{
    public class SequenceNumberGenerator_Test
    {
        private readonly ISequenceNumberGenerator _sequenceNumberGenerator;
        private readonly ITestOutputHelper _outputHelper;

        public SequenceNumberGenerator_Test(ITestOutputHelper outputHelper)
        {
            IConfigurationBuilder builder = new ConfigurationBuilder();
            builder.AddInMemoryCollection(new Dictionary<string, string>
            {
                 { "Redis:Configuration","127.0.0.1:6379"},
            });
            IConfigurationRoot configurationRoot = builder.Build();
            _sequenceNumberGenerator = new SequenceNumberGenerator(configurationRoot);
            _outputHelper = outputHelper;
        }

        [Fact]
        public async Task Generate_Test()
        {
            string key = "orderNumber" + Guid.NewGuid();
            string number = await _sequenceNumberGenerator.GenerateAsync(key, 4);
            Assert.Equal("0001", number);
        }

        [Fact]
        public void Generate2_Test()
        {
            string key = "orderNumber" + Guid.NewGuid();

            Parallel.For(1, 1000, async _ =>
            {
                long number = await _sequenceNumberGenerator.GenerateAsync(key);
                _outputHelper.WriteLine("number:" + number);
            });
        }
    }
}

运行测试
image.png
image.png
可以看到实现没有问题。

本文作者:hiwwwk

本文链接:https://www.cnblogs.com/wwwk/p/15894083.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   hiwwwk  阅读(372)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起