kevinyao0901 3 тижднів тому
джерело
коміт
7fcfdf59ae
1 змінених файлів з 41 додано та 10 видалено
  1. +41
    -10
      db/db_impl.cc

+ 41
- 10
db/db_impl.cc Переглянути файл

@ -1240,12 +1240,22 @@ Status DBImpl::Put(const WriteOptions& o, const Slice& key, const Slice& val) {
WriteBatch indexBatch;
Status s;
// 记录已插入的主数据库的键
std::vector<Slice> keysInserted;
// 如果当前是 indexDb_ 的 Put 操作,只提交主数据库的事务
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);
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);
if (!s.ok()) {
// 如果二级索引数据库写入失败,回滚主数据库的写入
// 回滚操作:删除已经写入主数据库的键
// 回滚操作:从主数据库中恢复原始键值对
// 恢复已插入的键,获取原始值(假设原始值未被删除)
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);
if (!rollbackStatus.ok()) {
return rollbackStatus;
return rollbackStatus; // 如果回滚操作失败,返回回滚错误
}
return s;
return s; // 返回二级索引数据库写入失败的状态
}
} else {
// 如果是 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
//return DB::Put(o, key, val);
}
@ -1313,6 +1330,16 @@ Status DBImpl::Delete(const WriteOptions& options, const Slice& key) {
WriteBatch indexBatch;
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);
@ -1350,7 +1377,11 @@ Status DBImpl::Delete(const WriteOptions& options, const Slice& key) {
// 如果二级索引数据库删除失败,回滚主数据库的删除操作
// 回滚操作:重新插入已删除的主数据库的键
WriteBatch rollbackBatch;
rollbackBatch.Put(key, ""); // 将原始数据重新插入主数据库
if (!originalValue.empty()) {
rollbackBatch.Put(key, originalValue); // 恢复原始数据
} else {
rollbackBatch.Put(key, ""); // 如果原始值为空,使用空值恢复
}
Status rollbackStatus = this->Write(options, &rollbackBatch);
if (!rollbackStatus.ok()) {
return rollbackStatus;

Завантаження…
Відмінити
Зберегти