.NetCore利用Redis简单封装生成顺序号
前言
有不少业务场景下需要生成流水号,比较简单的情况是新建一个表,然后利用自增Id来实现。但这种实现弊端比较大,占用数据库资源,操作步骤也多。于是想到使用Redis更好,因为是基于内存操作的,速度快且具有原子性。
实现
新建项目RedisDemo
新建接口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
测试项目
将自带的类文件重命名为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);
});
}
}
}
运行测试
可以看到实现没有问题。
本文作者:hiwwwk
本文链接:https://www.cnblogs.com/wwwk/p/15894083.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步