文章目录
Exercise 1 + 2 + 5
BufferPoll
参数
-
private LockManager lockManager; // 锁的管理器,管理已经持有的锁
- PageLock:页面锁,某个事务持有的锁(两种类型,共享锁和排他锁)
// 锁 class PageLock{ private static final int SHARE = 0; private static final int EXCLUSIVE = 1; private TransactionId tid; private int type; public PageLock(TransactionId tid, int type){ this.tid = tid; this.type = type; } public TransactionId getTid(){ return tid; } public int getType(){ return type; } public void setType(int type){ this.type = type; } }- LockManager:锁管理器
class LockManager { ConcurrentHashMap<PageId, ConcurrentHashMap<TransactionId, PageLock>> lockMap = new ConcurrentHashMap<>(); /** * 获取锁 */ public synchronized boolean acquiredLock(PageId pageId, TransactionId tid, int requiredType) { // 判断当前页是否当前有锁 if (lockMap.get(pageId) == null) { // 创建锁 PageLock pageLock = new PageLock(tid, requiredType); ConcurrentHashMap<TransactionId, PageLock> pageLocks = new ConcurrentHashMap<>(); pageLocks.put(tid, pageLock); lockMap.put(pageId, pageLocks); return true; } // 获取当前锁的等待队列 ConcurrentHashMap<TransactionId, PageLock> pageLocks = lockMap.get(pageId); // tid 没有 Page 上的锁 if (pageLocks.get(tid) == null) { // 如果 当前页已经有锁 if (pageLocks.size() > 1) { // 如果是共享锁,新增获取对象 if (requiredType == PageLock.SHARE) { // tid 请求锁 PageLock pageLock = new PageLock(tid, PageLock.SHARE); pageLocks.put(tid, pageLock); lockMap.put(pageId, pageLocks); return true; } // 如果是排他锁 else if (requiredType == PageLock.EXCLUSIVE) { // tid 需要获取写锁,拒绝 return false; } } if (pageLocks.size() == 1) { // page 上有一个其他事务, 可能是写锁,也可能是读锁 PageLock curLock = null; for (PageLock lock : pageLocks.values()) { curLock = lock; } if (curLock.getType() == PageLock.SHARE) { // 如果请求的锁也是读锁 if (requiredType == PageLock.SHARE) { // tid 请求锁 PageLock pageLock = new PageLock(tid, PageLock.SHARE); pageLocks.put(tid, pageLock); lockMap.put(pageId, pageLocks); return true; } // 如果是独占锁 else if (requiredType == PageLock.EXCLUSIVE) { // tid 需要获取写锁,拒绝 return false; } } // 如果是独占锁 else if (curLock.getType() == PageLock.EXCLUSIVE) { // tid 需要获取写锁,拒绝 return false; } } } // 当前事务持有 Page 锁 else if (pageLocks.get(tid) != null) { PageLock pageLock = pageLocks.get(tid); // 事务上是写锁 if (pageLock.getType() == PageLock.SHARE) { // 新请求的是读锁 if (requiredType == PageLock.SHARE) { return true; } // 新请求是写锁 else if (requiredType == PageLock.EXCLUSIVE) { // 如果该页面上只有一个锁,就是该事务的读锁 if (pageLocks.size() == 1) { // 进行锁升级(升级为写锁) pageLock.setType(PageLock.EXCLUSIVE); pageLocks.put(tid, pageLock); return true; } // 大于一个锁,说明有其他事务有共享锁 else if (pageLocks.size() > 1) { // 不能进行锁的升级 return false; } } } // 事务上是写锁 // 无论请求的是读锁还是写锁,都可以直接返回获取 return pageLock.getType() == PageLock.EXCLUSIVE; } return false; } /** * 释放锁 */ public synchronized boolean releaseLock(TransactionId tid, PageId pageId) { // 判断是否持有锁 if (isHoldLock(tid, pageId)) { ConcurrentHashMap<TransactionId, PageLock> locks = lockMap.get(pageId); locks.remove(tid); if (locks.size() == 0) { lockMap.remove(pageId); } return true; } return false; } /** * 判断是否持有锁 */ public synchronized boolean isHoldLock(TransactionId tid, PageId pageId) { ConcurrentHashMap<TransactionId, PageLock> locks = lockMap.get(pageId); if (locks == null) { return false; } PageLock pageLock = locks.get(tid); if (pageLock == null) { return false; } return true; } /** * 完成事务后释放所有锁 */ public synchronized void completeTranslation(TransactionId tid) { // 遍历所有的页,如果对应事务持有锁就会释放 for (PageId pageId : lockMap

最低0.47元/天 解锁文章
360

被折叠的 条评论
为什么被折叠?



