DataLock | 数据锁、单据号码锁、并发锁(C#源码)|C/S开发框架

DataLock - 数据锁、单据号码锁、并发锁
一、DataLock说明
数据锁机制用于管理对共享资源的并发访问,确保数据的完整性和一致性。DataLock数据锁主要用于在多用户操作环境下,避免多用户并发操作,导致脏写、脏读以及脏数据形成。
二、应用场景
- 数据锁,用于处理特定的数据,比如用户A必须独占处理某种数据,执行数据锁后,用户B必须等待用户A处理完毕。
- 单据号码锁,用于生成唯一的单据号码,不会并发操作!
- 并发锁,处理有关并发方面的需求。
三、使用方法
3.1 数据锁标准使用方法
public string DoSomething()
{
var dataLock = new DataLock(db_System, "LockName", "测试业务锁");
try
{
dataLock.SetLock();
dataLock.Release();
return "测试成功!";
}
catch (Exception ex)
{
dataLock.Release();
throw ex;
}
}
3.2 生成唯一的单据号码、流水号码
public long GetNewGroupNo()
{
var dataLock = new DataLock(db_System, "LogisticGroup", "物流编号-单据号码锁");
try
{
dataLock.SetLock();
long lastNo = GetLastGroupNo();
long groupNo;
if (String.IsNullOrEmpty(dataLock.LockData.Data))
dataLock.LockData.Data = lastNo.ToString();
groupNo = ConvertEx.ToLong(dataLock.LockData.Data);
if (groupNo == 0) groupNo = lastNo;
if (groupNo < lastNo) groupNo = lastNo;
groupNo++;
dataLock.SetData(groupNo.ToString());
dataLock.Release();
return groupNo;
}
catch (Exception ex)
{
dataLock.Release();
throw ex;
}
}
四、DataLock 源码
public class DataLock
{
private DbFramework _EF;
private string _lockName;
private string _note;
private string _token;
private int _MAX_TRY_COUNT = 10;
private sys_DataLock _Data = null;
public sys_DataLock LockData { get { return _Data; } }
public DataLock(IDatabase db, string lockName, string note = null, int maxTryCount = 10)
{
_lockName = lockName;
_note = note;
_MAX_TRY_COUNT = maxTryCount;
_token = GetToken();
_EF = new DbFramework(db);
}
public bool IsLock()
{
if (_Data == null)
{
_Data = GetLock();
if (_Data == null) _Data = AddLock();
}
return _Data.IsLock;
}
public void SetLock()
{
for (int i = 1; i <= _MAX_TRY_COUNT; i++)
{
_Data = GetLock();
if (_Data == null) _Data = AddLock();
if (_Data.IsLock == false)
{
_Data.IsLock = true;
_Data.AccessTime = DateTime.Now;
_Data.AccessToken = _token;
_EF.UpdateObject<sys_DataLock>(_Data);
return;
}
else
{
Thread.Sleep(1000);
}
}
throw new Exception($"设置数据锁<{_lockName}>失败");
}
public void SetData(string data, string note = null)
{
_Data.Data = data;
_Data.Note = String.IsNullOrEmpty(note) ? _Data.Note : note;
_Data.AccessTime = DateTime.Now;
_EF.UpdateObject<sys_DataLock>(_Data, null, null, new string[] { "Data", "Note", "AccessTime" });
}
public void Release()
{
_Data.IsLock = false;
_Data.AccessTime = DateTime.Now;
_EF.UpdateObject<sys_DataLock>(_Data, new string[] { "AccessToken" });
}
private sys_DataLock AddLock()
{
sys_DataLock o = new sys_DataLock
{
LockName = this._lockName,
Note = this._note,
IsLock = false,
AccessTime = DateTime.Now,
AccessToken = _token,
};
bool ok = _EF.AddObject(o);
if (ok)
return o;
else
throw new Exception("添加锁失败!");
}
private sys_DataLock GetLock()
{
return _EF.Select<sys_DataLock>("LockName", _lockName);
}
private string GetToken()
{
long result = 1;
int index = 1;
byte[] bs = Guid.NewGuid().ToByteArray();
foreach (byte b in bs)
{
result *= ((int)b + index * 2);
index++;
}
var hex = string.Format("{0:x}", result);
return hex;
}
}
五、sys_DataLock 表结构
public class sys_DataLock
{
[IgnoreField]
public int isid { get; set; }
[KeyField]
public string LockName { get; set; }
public bool IsLock { get; set; }
public string Data { get; set; }
public string Note { get; set; }
public DateTime AccessTime { get; set; }
public string AccessToken { get; set; }
}
六、依赖项目
CSFramework.DB
https://www.cscode.net/archive/csframework.db/1630589248.html

扫一扫加作者微信