c++ mysql 锁_数据库读写锁的实现(C++)

本文介绍了一种C++实现的MySQL数据库读写锁机制,详细阐述了排它锁(X锁)和共享锁(S锁)的概念,并提供了程序的数据结构和源码。程序使用地图数据结构来跟踪数据对象的状态,处理Start、End、XLock、SLock、Unlock等请求,但不处理死锁检测。示例展示了如何通过类接口操作这些锁。
摘要由CSDN通过智能技术生成

一、基本概念

在数据库中,对某数据的两个基本操作为写和读。分布有两种锁控制:排它锁(X锁)、共享锁(S锁)。

排它锁(x锁):若事务T对数据D加X锁,则其他不论什么事务都不能再对D加不论什么类型的锁。直至T释放D上的X锁;

一般要求在改动数据前要向该数据加排它锁,所以排它锁又称为写锁。

共享锁(s锁):若事务T对数据D加S锁。则其他事务仅仅能对D加S锁,而不能加X锁,直至T释放D上的S锁;

一般要求在读取数据前要向该数据加共享锁。 所以共享锁又称读锁。

程序所收到的请求包含下面五种:Start、End、XLock、SLock、Unlock

Start:开启对应的事件请求

End:  关闭对应的事件请求

XLock: 对数据对象D加入X锁。进行写操作(当事件以对数据A加入S锁时,此时可升级为X锁)

SLock: 对数据对象D加入S锁,进行读操作

Unlock: 对数据对象D进行解锁(对数据D的X/S锁解绑。并检查等待队列)

本程序并不进行死锁检測以及死锁预防。对于等待队列採取FIFO原则进行。

二、数据结构

读写锁维护一个数据D的状态表,标记当前数据D的实时状态,锁表的信息随着事务的运行动态更新,反映当前的锁状态。

其数据结构例如以下图所看到的:

SouthEast

当中:mObjectList:为map结构的对象树。可方便高速查找对应对象。

objectName:为对象数据D的名称

curXLockTrans: 为当前写操作的事件

waitingTransList: 为写等待队列

shareList: 为共享集(当curXLockTrans不为空时,变为共享等待队列)

事件ID的数据结构例如以下:

dcbffc914b78ac89c2c175a5716a1834.png

当中:mTransId: 为map结构的事件树。能够高速的查找对应事件

tranId: 为事件名称

curLockObjList: 为此事件眼下所操作的对象列表

三、源码

本程序为所的锁管理接口。所以封装成类。方便程序调用。程序源代码能够点击这里下载。

数据结构例如以下:

class LMer {

private:

struct object

{

string objectName;

string curXLockTrans;

queue waitingTransList;

set shareList;

};

struct transId

{

string tranId;

set curLockObjList;

};

map mObjectList;

map mTransId;

public:

LMer(){}

string LMer::handleInput(vector& vInput);

void LMer::handleAction(string sAction, transId* trId, object* obj, string& result);

void LMer::diviTransID(transId* trId, object* pObj, string& result);

};逻辑结构实现例如以下:

string LMer::handleInput(vector& vInput)

{

string result = "";

//二參数输入

if (vInput.size() == 2)

{ //进程存在,进入下一步

map::iterator transIt = mTransId.find(vInput[1]);

if (transIt != mTransId.end())

{

//是否结束事件(结束事件队列中全部事件)

if (vInput[0] == "End")

{

result += "\tTransaction "+ vInput[1] +" ended\n\t\t\t";

//解绑进程全部事物

set::iterator obj_index;

while(transIt->second->curLockObjList.size() != 0)

{

obj_index = transIt->second->curLockObjList.begin();

diviTransID(transIt->second, *obj_index, result);

}

//清空请求事件

mTransId.erase(transIt);

}

}

else if(vInput[0] == "Start")//为start,创立进程

{

transId* pTransId = new transId();

pTransId->tranId = vInput[1];

//将此进程增加进程树中

mTransId[vInput[1]] = pTransId;

result += "Transaction " + vInput[1] +" started\n";

}

}

else //三參数输入

{ //创建新操作对象

if(mObjectList.find(vInput[2]) == mObjectList.end())

{

object* pObjectIndex = new object();

pObjectIndex->objectName = vInput[2];

pObjectIndex->curXLockTrans = "";

mObjectList[vInput[2]] = pObjectIndex;

}

if (vInput[0] == "Unlock")

{

//解锁trans->obj

diviTransID(mTransId[vInput[1]], mObjectList[vInput[2]], result);

}

else//进行常规处理(Xlock、Slock)

{

//进行处理

handleAction(vInput[0], mTransId[vInput[1]], mObjectList[vInput[2]], result);

}

}

return result;

}

void LMer::handleAction(string sAction, transId* trId, object* obj, string& result)

{

//检查是否有占用

if (sAction == "SLock")

{

if (obj->curXLockTrans == "")

{

obj->shareList.insert(trId->tranId);

trId->curLockObjList.insert(obj);

result += "S-Lock granted to "+ trId->tranId +"\n";

}

else//被占用

{

obj->shareList.insert(trId->tranId);

result += "Waiting for lock (X-lock held by: "+ obj->curXLockTrans +")\n";

}

}

else if(sAction == "XLock")

{

//未有写操作

if (obj->curXLockTrans == "")

{

int shareNum = obj->shareList.size();

if (shareNum > 1)

{

string sTemp = "";

for (set::iterator it_index = obj->shareList.begin();

it_index != obj->shareList.end(); it_index++)

{

sTemp += " " + *it_index;

}

obj->waitingTransList.push(trId->tranId);

result += "Waiting for lock (S-lock held by:" + sTemp + "\n";

}

else if (shareNum == 1)

{

//update

if (*(obj->shareList.begin()) == trId->tranId)

{

obj->curXLockTrans = trId->tranId;

obj->shareList.clear();

result += "Upgrade to XLock granted\n";

}

else

{

obj->waitingTransList.push(trId->tranId);

result += "Waiting for lock (S-lock held by:" + *(obj->shareList.begin()) + ")\n";

}

}

else if (shareNum == 0)

{

obj->curXLockTrans = trId->tranId;

trId->curLockObjList.insert(obj);

result += "XLock granted\n";

}

}

else//当前存在写操作

{

obj->waitingTransList.push(trId->tranId);

result += "Waiting for lock (X-lock held by: "+ obj->curXLockTrans +")\n";

}

}

}

void LMer::diviTransID(transId* trId, object* pObj, string& result)

{

if(pObj->curXLockTrans != "")

{

//对写操作解绑

if (pObj->curXLockTrans == trId->tranId)

{

pObj->curXLockTrans = "";

trId->curLockObjList.erase(pObj);

result += "Lock released\n\t\t\t";

}

else

{

result += "I can not find the transaction.\n\t\t\t";

}

}//对共享读集合解绑

else

{

set::iterator shareIndex = pObj->shareList.find(trId->tranId);

if (shareIndex != pObj->shareList.end())

{

pObj->shareList.erase(shareIndex);

trId->curLockObjList.erase(pObj);

result += "Lock released\n\t\t\t";

}

else

{

result += "I can not find the transaction.\n\t\t\t";

}

}

//查看写等待队列

if (pObj->waitingTransList.size() != 0)

{

pObj->curXLockTrans = pObj->waitingTransList.front();

pObj->waitingTransList.pop();

result += "X-Lock on "+ pObj->objectName +" granted to "+ pObj->curXLockTrans +"\n";

}//查看共享队列

else if (pObj->shareList.size() != 0)

{

string temp = "";

for(set::iterator it_index = pObj->shareList.begin();

it_index != pObj->shareList.end(); it_index++)

{

temp += " " + *it_index;

}

result += "S-Lock on "+ pObj->objectName +" granted to "+ temp +"\n";

}

}

四、程序执行

程序数据输入例如以下:

8e9aa74eefe1d7495c15eb27d7506978.png

执行后得到结果例如以下:

SouthEast

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值