• Flume学习——BasicTransactionSemantics


    org.apache.flume.channel.BasicTransactionSemantics

    An implementation of basic Transaction semantics designed to work in concert with BasicChannelSemantics to simplify creation of robust Channel implementations. This class ensures that each transaction implementation method is called only while the transaction is in the correct state for that method, and only by the thread that created the transaction. Nested calls to begin() and close() are supported as long as they are balanced.

    Subclasses need only implement doPut, doTake, doCommit, and doRollback, and the developer can rest assured that those methods are called only after transaction state preconditions have been properly met. doBegin and doClose may also be implemented if there is work to be done at those points.

    All InterruptedException exceptions thrown from the implementations of the doXXX methods are automatically wrapped to become ChannelExceptions, but only after restoring the interrupted status of the thread so that any subsequent blocking method calls will themselves throw InterruptedException rather than blocking. The exception to this rule is doTake, which simply returns null instead of wrapping and propagating the InterruptedException, though it still first restores the interrupted status of the thread.

    BasicTransactionSemantics实现了Transaction的基本语法,与BasicChannelSemantics一起工作,来使得创建健壮的Channel实现更加简单。这个类确保了一个事务中的操作(如take(),put())只有在当前的事务处于对应的状态时才被调用,并且只有创建了当前的事务的线程才能调用这些事务中的操作。对begin()和close()的嵌套调用是支持的,只要对它们的调用保持平衡(这句不怎么明白,对同一个transaction对象嵌套调用这两个方法明显不行,应该是不同的transaction对象的close和begin方法可以嵌套)。

    它的子类可以只实现doPut, doTake, doCommit和doCommit、doRollback方法,而不必再设法确保这些方法只有在正确的事务状态下才被调用。当doBegin和doClose也有特殊的操作时,也可以实现这两个方法。

    在doXXX方法中抛出的InterruptedException都被包装进ChannelException中,但这是在恢复了当前线程的interrupted状态之后,这样接下的blocking method call就会抛出InterruptedException,而不是进入阻塞状态。这个规则的的例外是doTake,当只是返回null,而不是包装、传播InterruptedException,但是doTake仍然先恢复了线程的interrupted状态。

    BasicTransactionSemantics实现了跟事务范围内各个操作有关方法。

    Method Summary
     void begin() 
              Starts a transaction boundary for the current channel operation.
     void close() 
              Ends a transaction boundary for the current channel operation.
     void commit() 
              Indicates that the transaction can be successfully committed.
    protected  void doBegin() 
               
    protected  void doClose() 
               
    protected abstract  void doCommit() 
               
    protected abstract  void doPut(Event event) 
               
    protected abstract  void doRollback() 
               
    protected abstract  Event doTake() 
               
    protected  BasicTransactionSemantics.State getState() 
               
    protected  void put(Event event) 
               The method to which BasicChannelSemantics delegates calls to put.
     void rollback() 
              Indicates that the transaction can must be aborted.
    protected  Event take() 
               The method to which BasicChannelSemantics delegates calls to take.
     String toString() 
               


    其中put take begin close commit rollback 的结构都很相似。主要结构都是确保这些操作时Transaction在正确的对应状态,然后调用doXXX方法。如果当前的线程不拥有当前的事务或者事务的状态不对,就抛出异常。如果doXXX方法抛出InterruptedException就通过Thread.currentThread.interrupt()方法恢复当前线程的interrupted状态,然后将捕获的InterruptedException包装成一个ChannelException,抛出。

      @Override
      public void rollback() {
        Preconditions.checkState(Thread.currentThread().getId() == initialThreadId,
            "rollback() called from different thread than getTransaction()!");
        Preconditions.checkState(state.equals(State.OPEN),
            "rollback() called when transaction is %s!", state);
    
        state = State.COMPLETED;
        try {
          doRollback();
        } catch (InterruptedException e) {
          Thread.currentThread().interrupt();
          throw new ChannelException(e.toString(), e);
        }
      }

     可见BasicTransactionSemantic类确保了事务中各个操作的执行顺序。并且对执行各个操作中可能抛出的InterruptedException进行了一次封装。它的各个子类只需要实现具体的操作。

    以BasicChannelSemantic类的代码可以看出,它对Channel接口定义的put(event)和take()的实现是把这两个方法代理给了自己线程中的BasicTransactionSemantic的put和get方法。而BasicTransactionSemantic中这两个方法

      protected Event take() {
        Preconditions.checkState(Thread.currentThread().getId() == initialThreadId,
            "take() called from different thread than getTransaction()!");
        Preconditions.checkState(state.equals(State.OPEN),
            "take() called when transaction is %s!", state);
    
        try {
          return doTake();
        } catch (InterruptedException e) {
          Thread.currentThread().interrupt();
          return null;
        }
      }

    是交给了子类要实现的doTake和doPut方法。因此一个Channel的具体实现,其消息的处理逻辑是由自己的getTransaction()方法返回的Trasaction对象来实现的。正如MemoryChannel的内部类MemoryTransaction所做的一样。

  • 相关阅读:
    Android Studio运行Hello World程序
    WPF,回车即是tab
    phpmyadmin上在某数据库里创建函数
    thinkphp项目部署在phpstudy里的nginx上
    《原创视频》牛腩学docker简记
    visual studio添加docker支持简记
    edge 浏览器中数字显示为链接
    JSON.net 在实体类中自定义日期的格式
    让easyui 的alert 消息框中的确定按钮支持空格键
    修复百度编辑器(UM)禁用时上传图片按钮还可点击的BUG;
  • 原文地址:https://www.cnblogs.com/devos/p/3440308.html
Copyright © 2020-2023  润新知