数据库读写锁的C++实现

一、基本概念

在数据库中,对某数据的两个基本操作为写和读,分布有两种锁控制:排它锁(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的实时状态,锁表的信息随着事务的执行动态更新,反映当前的锁状态。

其数据结构如下图所示:

其中:mObjectList:为map结构的对象树,可方便快速查找相应对象。

        objectName:为对象数据D的名称

        curXLockTrans: 为当前写操作的事件

        waitingTransList: 为写等待队列

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

事件ID的数据结构如下:

其中:mTransId: 为map结构的事件树,可以快速的查找相应事件

     tranId: 为事件名称

        curLockObjList: 为此事件目前所操作的对象列表

三、源代码

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

数据结构如下:

 1 class LMer {
 2 
 3 private:
 4  
 5     struct object
 6     {
 7         string objectName;
 8         string curXLockTrans;
 9         queue<string> waitingTransList;
10         set<string> shareList;
11     };
12 
13     struct transId
14     {
15         string   tranId;
16         set<object*>  curLockObjList;
17     };
18 
19     map<string, object*> mObjectList; 
20     map<string, transId*> mTransId;
21 
22 public:
23     
24     LMer(){}
25     string LMer::handleInput(vector<string>& vInput);
26     void LMer::handleAction(string sAction, transId* trId, object* obj, string& result);
27     void LMer::diviTransID(transId* trId, object* pObj, string& result);
28 };

逻辑结构实现如下:

  1 string LMer::handleInput(vector<string>& vInput)
  2 {
  3     string result = "";
  4     //二参数输入
  5     if (vInput.size() == 2)
  6     {    //进程存在,进入下一步
  7         map<string, transId*>::iterator transIt = mTransId.find(vInput[1]);
  8         if (transIt != mTransId.end())
  9         {
 10             //是否结束事件(结束事件队列中所有事件)
 11             if (vInput[0] == "End")
 12             {
 13                 result += "\tTransaction "+ vInput[1] +" ended\n\t\t\t";
 14                 //解绑进程所有事物
 15                 set<object*>::iterator obj_index;
 16                 while(transIt->second->curLockObjList.size() != 0)
 17                 {
 18                     obj_index = transIt->second->curLockObjList.begin();
 19                     diviTransID(transIt->second, *obj_index, result);
 20                 }
 21                 //清空请求事件
 22                 mTransId.erase(transIt);
 23             }
 24         }
 25         else if(vInput[0] == "Start")//为start,创立进程
 26         {
 27             transId* pTransId = new transId();
 28             pTransId->tranId = vInput[1];
 29             //将此进程加入进程树中
 30             mTransId[vInput[1]] = pTransId;
 31             result += "Transaction " + vInput[1] +" started\n";
 32         }
 33     }
 34     else //三参数输入 
 35     {    //创建新操作对象
 36         if(mObjectList.find(vInput[2]) == mObjectList.end())
 37         {
 38             object* pObjectIndex = new object();
 39             pObjectIndex->objectName = vInput[2];
 40             pObjectIndex->curXLockTrans = "";
 41             mObjectList[vInput[2]] = pObjectIndex;
 42         }
 43 
 44         if (vInput[0] == "Unlock")
 45         {
 46             //解锁trans->obj
 47             diviTransID(mTransId[vInput[1]], mObjectList[vInput[2]], result);
 48         }
 49         else//进行常规处理(Xlock、Slock)
 50         {
 51             //进行处理
 52             handleAction(vInput[0], mTransId[vInput[1]], mObjectList[vInput[2]], result);
 53         }
 54     }
 55 
 56     return result;
 57 }
 58 
 59 void LMer::handleAction(string sAction, transId* trId, object* obj, string& result)
 60 {
 61     //检查是否有占用
 62     if (sAction == "SLock")
 63     {
 64         if (obj->curXLockTrans == "")
 65         {
 66             obj->shareList.insert(trId->tranId);
 67             trId->curLockObjList.insert(obj);
 68             result += "S-Lock granted to "+ trId->tranId +"\n";
 69         }
 70         else//被占用
 71         {
 72             obj->shareList.insert(trId->tranId);
 73             result += "Waiting for lock (X-lock held by: "+ obj->curXLockTrans +")\n";
 74         }
 75     }
 76     else if(sAction == "XLock")
 77     {
 78         //未有写操作
 79         if (obj->curXLockTrans == "")
 80         {
 81             int shareNum = obj->shareList.size();
 82             if (shareNum > 1)
 83             {
 84                 string sTemp = "";
 85                 for (set<string>::iterator it_index = obj->shareList.begin();
 86                     it_index != obj->shareList.end(); it_index++)
 87                 {
 88                     sTemp += " " + *it_index;
 89                 }
 90                 obj->waitingTransList.push(trId->tranId);
 91                 result += "Waiting for lock (S-lock held by:" + sTemp + "\n";
 92             }
 93             else if (shareNum == 1)
 94             {
 95                 //update
 96                 if (*(obj->shareList.begin()) == trId->tranId)
 97                 {
 98                     obj->curXLockTrans = trId->tranId;
 99                     obj->shareList.clear();
100                     result += "Upgrade to XLock granted\n";
101                 }
102                 else
103                 {
104                     obj->waitingTransList.push(trId->tranId);
105                     result += "Waiting for lock (S-lock held by:" + *(obj->shareList.begin()) + ")\n";
106                 }
107             }
108             else if (shareNum == 0)
109             {
110                 obj->curXLockTrans = trId->tranId;
111                 trId->curLockObjList.insert(obj);
112                 result += "XLock granted\n";
113             }
114         }
115         else//当前存在写操作
116         {
117             obj->waitingTransList.push(trId->tranId);
118             result += "Waiting for lock (X-lock held by: "+ obj->curXLockTrans +")\n";
119         }
120     }
121 }
122 
123 void LMer::diviTransID(transId* trId, object* pObj, string& result)
124 {
125     if(pObj->curXLockTrans != "")
126     {
127         //对写操作解绑
128         if (pObj->curXLockTrans == trId->tranId)
129         {
130             pObj->curXLockTrans = "";
131             trId->curLockObjList.erase(pObj);
132             result += "Lock released\n\t\t\t";
133         }
134         else
135         {
136             result += "I can not find the transaction.\n\t\t\t";
137         }
138     }//对共享读集合解绑
139     else 
140     {
141         set<string>::iterator shareIndex = pObj->shareList.find(trId->tranId);
142         if (shareIndex != pObj->shareList.end())
143         {
144             pObj->shareList.erase(shareIndex);
145             trId->curLockObjList.erase(pObj);
146             result += "Lock released\n\t\t\t";
147         }
148         else
149         {
150             result += "I can not find the transaction.\n\t\t\t";
151         }
152     }
153     //查看写等待队列
154     if (pObj->waitingTransList.size() != 0)
155     {
156         pObj->curXLockTrans = pObj->waitingTransList.front();
157         pObj->waitingTransList.pop();
158         result += "X-Lock on "+ pObj->objectName +" granted to "+ pObj->curXLockTrans +"\n";
159     }//查看共享队列
160     else if (pObj->shareList.size() != 0)
161     {
162         string temp = "";
163         for(set<string>::iterator it_index = pObj->shareList.begin();
164             it_index != pObj->shareList.end(); it_index++)
165         {
166             temp += " " + *it_index;
167         }
168         result += "S-Lock on "+ pObj->objectName +" granted to "+ temp +"\n";
169     }
170 }

四、程序运行

程序数据输入如下:

运行后得到结果如下:

 

转载于:https://www.cnblogs.com/michaelGD/archive/2013/01/24/2844340.html

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个简单的数据库读写示例代码: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sqlite3.h> int main() { sqlite3 *db; char *errMsg = 0; int rc; char *sql; const char* data = "Callback function called"; rc = sqlite3_open("test.db", &db); if (rc != SQLITE_OK) { fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db)); sqlite3_close(db); exit(1); } // create table sql = "CREATE TABLE STUDENTS(ID INT PRIMARY KEY NOT NULL, NAME TEXT NOT NULL, AGE INT NOT NULL);"; rc = sqlite3_exec(db, sql, 0, 0, &errMsg); if (rc != SQLITE_OK) { fprintf(stderr, "SQL error: %s\n", errMsg); sqlite3_free(errMsg); } else { printf("Table created successfully\n"); } // insert data sql = "INSERT INTO STUDENTS (ID, NAME, AGE) VALUES (1, 'John Smith', 20);"; rc = sqlite3_exec(db, sql, 0, 0, &errMsg); if (rc != SQLITE_OK) { fprintf(stderr, "SQL error: %s\n", errMsg); sqlite3_free(errMsg); } else { printf("Data inserted successfully\n"); } // read data sql = "SELECT * from STUDENTS"; rc = sqlite3_exec(db, sql, callback, (void*)data, &errMsg); if (rc != SQLITE_OK) { fprintf(stderr, "SQL error: %s\n", errMsg); sqlite3_free(errMsg); } else { printf("Data read successfully\n"); } sqlite3_close(db); return 0; } static int callback(void *data, int argc, char** argv, char** azColName){ int i; printf("%s:\n", (const char*)data); for(i=0; i<argc; i++){ printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL"); } printf("\n"); return 0; } ``` 在上面的示例中,我们使用了SQLite3数据库,并使用了sqlite3库提供的函数来进行数据库的创建、写入和读取操作。首先,我们使用sqlite3_open()函数打开了一个名为“test.db”的数据库。接下来,我们使用sqlite3_exec()函数对数据库执行了一些操作,包括创建表格、插入数据、读取数据等。我们还实现了一个回调函数,用于处理读取数据后的回调操作。 需要注意的是,本示例代码仅供参考,实际应用中需要根据具体需求进行修改和优化。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值