博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
.net core 下的分布式事务锁
阅读量:5142 次
发布时间:2019-06-13

本文共 4248 字,大约阅读时间需要 14 分钟。

原文:

目录

系统分布式锁的用法

公司框架新增功能分布式锁:

锁的性能之王: 缓存 > Zookeeper >= 数据库

锁的实现

实现原理:核心采用StackExchange.Redis的LockTake方法实现。

支持同步获取锁,或者等待直到超时获取锁。

///     /// 分布式锁,提供全局分布式锁支持,以resource redis为基础    /// 这个锁只能通过RpcContext来获取,通过自己手动释放    ///     public sealed class DistributedLock    {
private static readonly TimeSpan DefaultAbandonmentCheckFrequency = TimeSpan.FromSeconds(2); public readonly string lockName; private readonly string lockValue; private readonly int checkTimeSpan = 50; //ms private readonly int autoDelete; private DistributedLock() {
} /// /// /// /// /// 自动删除,ms,默认 60s /// 如果不能获取锁,重复检查间隔:默认 50ms internal DistributedLock(string lockName, int autoDelete = 60000,int checkTimeSpan = 50) {
// note that just Global\ is not a valid name if (string.IsNullOrEmpty(lockName)) throw new ArgumentNullException("lockName不能为空"); if (null == ResourceCache.Instance) throw new Exception(@"ResourceCache 没有配置或无法连接"); this.checkTimeSpan = Math.Max(checkTimeSpan,1); this.autoDelete = Math.Max(autoDelete,1); this.lockName = lockName; this.lockValue = lockName; } /// /// 获取锁 /// /// 超时为null,则尝试一次即返回 ///
获取锁成功?
internal bool Acquire(TimeSpan? timeout = null) {
bool bLock = false; var dtStart = DateTime.Now.Ticks; while (!bLock) {
bLock = TryAcquireOnce(); if (timeout == null) {
break; } if (!bLock) {
Thread.Sleep(this.checkTimeSpan); } var ts = new TimeSpan(DateTime.Now.Ticks - dtStart); if (ts >= timeout) {
break; } } return bLock; } //此处采用框架上下文管理分布式事务锁的释放,代码略。 //public void Dispose() //{
// LockManager.ReleaseLock(this); //} internal void Release() {
try {
var bRtn = ResourceCache.Instance.LockRelease(this.lockName, this.lockValue); Trace.WriteLine($"释放锁 {this.lockName}:{bRtn}"); } catch (Exception e) {
LogTextWriter.Write($"释放锁失败,系统自动超时释放:{this.lockName}"); } } /// /// 释放锁 /// public void ReleaseLock() {
LockManager.ReleaseLock(this); } private bool TryAcquireOnce() {
try {
Trace.WriteLine($"{Thread.CurrentThread.ManagedThreadId}:TryAcquireOnce"); var @lock = ResourceCache.Instance.LockTake(this.lockName, this.lockValue, new TimeSpan(0, 0, 0, 0, this.autoDelete)); return @lock; } catch (Exception e) {
return false; } } }

锁的使用

在当前上下文中获取一个分布式锁,第一个获取锁的将执行依赖当前key(一般为业务主键)的完整业务流程(包括多个微服务之间的调用和数据库的访问;

后来者将无法获取锁,根据返回的结果来判断是否进入流程,如果返回的锁为null将不能执行下面的流程,要么重试等待锁释放,要么返回错误.

锁的调用一般流程:

var qtLock=TryGetLock(lockKey);        if(qtLock==null)         {
//提示不能同时执行操作 return; } else {
//进行业务流程 } //最后别忘了 qtLock.ReleaseLock();

API内的范例:

code = StatusCode.OK;  //传入超时时间,可以一直等待到超时过期 var lockSaveReceipt = this.Context.TryGetLock($"{nameof(SaveReceipt)}.{valueArgs.ReceiptArgs.ReceiptId}"); if (lockSaveReceipt == null) {
code = PublicErrorCode.SaveReceiptByUsed.ToCode(); return null; } try{
//todo 业务操作1 //todo 业务操作2 //... } finally {
lockSaveReceipt.ReleaseLock(); }

在此我向大家推荐一个微服务架构学习交流群。交流学习群号:864759589 里面会分享一些资深架构师录制的视频录像:高并发、高性能、分布式、微服务架构的原理,分布式架构等这些成为架构师必备的知识体系。

在这里插入图片描述


引用链接

  1. 本节源码:
posted on
2019-01-18 10:32 阅读(
...) 评论(
...)

转载于:https://www.cnblogs.com/lonelyxmas/p/10286349.html

你可能感兴趣的文章
CSS属性值currentColor
查看>>
java可重入锁reentrantlock
查看>>
浅谈卷积神经网络及matlab实现
查看>>
解决ajax请求cors跨域问题
查看>>
《收获,不止Oracle》pdf
查看>>
LinkedList<E>源码分析
查看>>
Real-Time Rendering 笔记
查看>>
如何理解HTML结构的语义化
查看>>
Activity之间的跳转:
查看>>
实验四2
查看>>
Android现学现用第十一天
查看>>
多路复用
查看>>
Python数据可视化之Pygal(雷达图)
查看>>
Java学习笔记--字符串和文件IO
查看>>
转 Silverlight开发历程—(画刷与着色之线性渐变画刷)
查看>>
SQL语法(3)
查看>>
在js在添版本号
查看>>
sublime3
查看>>
Exception Type: IntegrityError 数据完整性错误
查看>>
Nuget:Newtonsoft.Json
查看>>