首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >聊聊claudb的transaction command

聊聊claudb的transaction command

原创
作者头像
code4it
修改2020-08-31 10:08:04
3250
修改2020-08-31 10:08:04
举报
文章被收录于专栏:码匠的流水账码匠的流水账

本文主要研究一下claudb的transaction command

TransactionState

claudb-1.7.1/src/main/java/com/github/tonivade/claudb/TransactionState.java

public class TransactionState implements Iterable<Request> {
​
  private List<Request> requests = new LinkedList<>();
​
  public void enqueue(Request request) {
    requests.add(request);
  }
​
  public int size() {
    return requests.size();
  }
​
  @Override
  public Iterator<Request> iterator() {
    return requests.iterator();
  }
}
  • TransactionState实现了Iterable<Request>接口,它定义了requests属性,提供了enqueue方法将request添加到requests中

MultiCommand

claudb-1.7.1/src/main/java/com/github/tonivade/claudb/command/transaction/MultiCommand.java

@Command("multi")
@TxIgnore
public class MultiCommand implements DBCommand {
​
  private static final String TRASACTION_KEY = "tx";
​
  @Override
  public RedisToken execute(Database db, Request request) {
    if (!isTxActive(request.getSession())) {
      createTransaction(request.getSession());
      return responseOk();
    } else {
      return error("ERR MULTI calls can not be nested");
    }
  }
​
  private void createTransaction(Session session) {
    session.putValue(TRASACTION_KEY, new TransactionState());
  }
​
  private boolean isTxActive(Session session) {
    return session.getValue(TRASACTION_KEY).isPresent();
  }
}
  • MultiCommand实现了DBCommand接口,其execute方法先判断isTxActive,非active的话才createTransaction

ExecCommand

claudb-1.7.1/src/main/java/com/github/tonivade/claudb/command/transaction/ExecCommand.java

@Command("exec")
@TxIgnore
public class ExecCommand implements DBCommand {
​
  @Override
  public RedisToken execute(Database db, Request request) {
    Option<TransactionState> transaction = getTransactionIfExists(request.getSession());
    if (transaction.isPresent()) {
      DBServerContext server = getClauDB(request.getServerContext());
      List<RedisToken> responses = new ArrayList<>();
      for (Request queuedRequest : transaction.get()) {
        responses.add(executeCommand(server, queuedRequest));
      }
      return RedisToken.array(responses);
    } else {
      return RedisToken.error("ERR EXEC without MULTI");
    }
  }
​
  private RedisToken executeCommand(DBServerContext server, Request queuedRequest) {
    RespCommand command = server.getCommand(queuedRequest.getCommand());
    return command.execute(queuedRequest);
  }
​
  private Option<TransactionState> getTransactionIfExists(Session session) {
    return session.removeValue("tx");
  }
}
  • ExecCommand实现了DBCommand接口,其execute方法先通过getTransactionIfExists获取transaction,若transaction不存在则报错,存在的话则遍历transaction的queuedRequest,挨个执行executeCommand(server, queuedRequest)

DiscardCommand

claudb-1.7.1/src/main/java/com/github/tonivade/claudb/command/transaction/DiscardCommand.java

@Command("discard")
@TxIgnore
public class DiscardCommand implements DBCommand {
​
  private static final String TX_KEY = "tx";
​
  @Override
  public RedisToken execute(Database db, Request request) {
    removeTransactionIfExists(request.getSession());
​
    return RedisToken.responseOk();
  }
​
  private Option<TransactionState> removeTransactionIfExists(Session session) {
    return session.removeValue(TX_KEY);
  }
}
  • DiscardCommand实现了DBCommand接口,其execute方法执行removeTransactionIfExists(request.getSession())

小结

claudb transaction相关的command有MultiCommand、ExecCommand、DiscardCommand

doc

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • TransactionState
  • MultiCommand
  • ExecCommand
  • DiscardCommand
  • 小结
  • doc
相关产品与服务
云数据库 Redis
腾讯云数据库 Redis(TencentDB for Redis)是腾讯云打造的兼容 Redis 协议的缓存和存储服务。丰富的数据结构能帮助您完成不同类型的业务场景开发。支持主从热备,提供自动容灾切换、数据备份、故障迁移、实例监控、在线扩容、数据回档等全套的数据库服务。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档