|
@ -1240,12 +1240,22 @@ Status DBImpl::Put(const WriteOptions& o, const Slice& key, const Slice& val) { |
|
|
WriteBatch indexBatch; |
|
|
WriteBatch indexBatch; |
|
|
Status s; |
|
|
Status s; |
|
|
|
|
|
|
|
|
|
|
|
// 记录已插入的主数据库的键
|
|
|
|
|
|
std::vector<Slice> keysInserted; |
|
|
|
|
|
|
|
|
// 如果当前是 indexDb_ 的 Put 操作,只提交主数据库的事务
|
|
|
// 如果当前是 indexDb_ 的 Put 操作,只提交主数据库的事务
|
|
|
if (indexDb_ != nullptr) { |
|
|
if (indexDb_ != nullptr) { |
|
|
// 记录已插入的主数据库的键
|
|
|
|
|
|
std::vector<Slice> keysInserted; |
|
|
|
|
|
|
|
|
// 获取原始值:首先查询主数据库是否已经存在该键
|
|
|
|
|
|
std::string originalValue; |
|
|
|
|
|
|
|
|
|
|
|
// 使用 ReadOptions 来获取原始值
|
|
|
|
|
|
ReadOptions readOptions; // 创建 ReadOptions 实例
|
|
|
|
|
|
Status getStatus = this->Get(readOptions, key, &originalValue); // 获取原始值
|
|
|
|
|
|
if (!getStatus.ok() && !getStatus.IsNotFound()) { |
|
|
|
|
|
return getStatus; // 如果获取原始值失败,直接返回错误
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
// 在主数据库写入数据
|
|
|
|
|
|
|
|
|
// 在主数据库写入新数据
|
|
|
batch.Put(key, val); |
|
|
batch.Put(key, val); |
|
|
keysInserted.push_back(key); |
|
|
keysInserted.push_back(key); |
|
|
|
|
|
|
|
@ -1280,18 +1290,25 @@ Status DBImpl::Put(const WriteOptions& o, const Slice& key, const Slice& val) { |
|
|
s = indexDb_->Write(o, &indexBatch); |
|
|
s = indexDb_->Write(o, &indexBatch); |
|
|
if (!s.ok()) { |
|
|
if (!s.ok()) { |
|
|
// 如果二级索引数据库写入失败,回滚主数据库的写入
|
|
|
// 如果二级索引数据库写入失败,回滚主数据库的写入
|
|
|
// 回滚操作:删除已经写入主数据库的键
|
|
|
|
|
|
|
|
|
// 回滚操作:从主数据库中恢复原始键值对
|
|
|
|
|
|
|
|
|
|
|
|
// 恢复已插入的键,获取原始值(假设原始值未被删除)
|
|
|
for (const auto& insertedKey : keysInserted) { |
|
|
for (const auto& insertedKey : keysInserted) { |
|
|
batch.Delete(insertedKey); // 撤销主数据库的插入操作
|
|
|
|
|
|
|
|
|
if (!originalValue.empty()) { |
|
|
|
|
|
batch.Put(insertedKey, Slice(originalValue)); // 恢复原始值
|
|
|
|
|
|
} else { |
|
|
|
|
|
// 如果获取原始值失败,回滚操作就是删除该键
|
|
|
|
|
|
batch.Delete(insertedKey); |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// 执行回滚:将主数据库的删除操作写入
|
|
|
|
|
|
|
|
|
// 执行回滚:将主数据库的恢复操作写入
|
|
|
Status rollbackStatus = this->Write(o, &batch); |
|
|
Status rollbackStatus = this->Write(o, &batch); |
|
|
if (!rollbackStatus.ok()) { |
|
|
if (!rollbackStatus.ok()) { |
|
|
return rollbackStatus; |
|
|
|
|
|
|
|
|
return rollbackStatus; // 如果回滚操作失败,返回回滚错误
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
return s; |
|
|
|
|
|
|
|
|
return s; // 返回二级索引数据库写入失败的状态
|
|
|
} |
|
|
} |
|
|
} else { |
|
|
} else { |
|
|
// 如果是 indexDb_ 调用 Put,则只提交主数据库的 WriteBatch
|
|
|
// 如果是 indexDb_ 调用 Put,则只提交主数据库的 WriteBatch
|
|
@ -1302,7 +1319,7 @@ Status DBImpl::Put(const WriteOptions& o, const Slice& key, const Slice& val) { |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
return Status::OK(); |
|
|
|
|
|
|
|
|
return Status::OK(); |
|
|
//ToDo end
|
|
|
//ToDo end
|
|
|
//return DB::Put(o, key, val);
|
|
|
//return DB::Put(o, key, val);
|
|
|
} |
|
|
} |
|
@ -1313,6 +1330,16 @@ Status DBImpl::Delete(const WriteOptions& options, const Slice& key) { |
|
|
WriteBatch indexBatch; |
|
|
WriteBatch indexBatch; |
|
|
Status s; |
|
|
Status s; |
|
|
|
|
|
|
|
|
|
|
|
// 记录已删除的主数据库的键和原始值
|
|
|
|
|
|
std::string originalValue; |
|
|
|
|
|
|
|
|
|
|
|
// 获取原始值:首先查询主数据库
|
|
|
|
|
|
ReadOptions readOptions; // 创建 ReadOptions 实例
|
|
|
|
|
|
Status getStatus = this->Get(readOptions, key, &originalValue); // 获取原始值
|
|
|
|
|
|
if (!getStatus.ok() && !getStatus.IsNotFound()) { |
|
|
|
|
|
return getStatus; // 如果获取原始值失败,直接返回错误
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
// 在主数据库删除数据
|
|
|
// 在主数据库删除数据
|
|
|
batch.Delete(key); |
|
|
batch.Delete(key); |
|
|
|
|
|
|
|
@ -1350,7 +1377,11 @@ Status DBImpl::Delete(const WriteOptions& options, const Slice& key) { |
|
|
// 如果二级索引数据库删除失败,回滚主数据库的删除操作
|
|
|
// 如果二级索引数据库删除失败,回滚主数据库的删除操作
|
|
|
// 回滚操作:重新插入已删除的主数据库的键
|
|
|
// 回滚操作:重新插入已删除的主数据库的键
|
|
|
WriteBatch rollbackBatch; |
|
|
WriteBatch rollbackBatch; |
|
|
rollbackBatch.Put(key, ""); // 将原始数据重新插入主数据库
|
|
|
|
|
|
|
|
|
if (!originalValue.empty()) { |
|
|
|
|
|
rollbackBatch.Put(key, originalValue); // 恢复原始数据
|
|
|
|
|
|
} else { |
|
|
|
|
|
rollbackBatch.Put(key, ""); // 如果原始值为空,使用空值恢复
|
|
|
|
|
|
} |
|
|
Status rollbackStatus = this->Write(options, &rollbackBatch); |
|
|
Status rollbackStatus = this->Write(options, &rollbackBatch); |
|
|
if (!rollbackStatus.ok()) { |
|
|
if (!rollbackStatus.ok()) { |
|
|
return rollbackStatus; |
|
|
return rollbackStatus; |
|
|