精华内容
下载资源
问答
  • 表单自动填写,网页自动提交工具

    千次下载 热门讨论 2012-11-06 10:02:04
    模拟人工提交网页表单操作,同时监控提交结果变化并报警提示或自动处理报警动作。可广泛用于注册表单、登陆表单、信息添加修改表单提交。 1、支持多任务多操作连续提交,实现无人值守。 2、支持通过多代理服务器访问...
  • 以下是本人总结处来的一些form的提交方式,网上还有别的提交方式,这里我总结了大小分为7类,其实就是三类的提交方式,若有哪里不对的,还请评论指出来,大家一起学习学习 1、无任何验证提交(最普通的提交) 该方式...

    以下是本人总结处来的一些form的提交方式,网上还有别的提交方式,这里我总结了大小分为7类,其实就是三类的提交方式,若有哪里不对的,还请评论指出来,大家一起学习学习

    1、无任何验证提交(最普通的提交)

    该方式不提供任何的验证方式,当我们点击提交时(提交的前提一定是 <input> 的type="submit"或者加粗样式<button>的type=“submit”)
    form直接与后台交互,后台通过表单里面的name属性来获取表单里的值

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>form表单提交</title>
    </head>
    <body>
    <!-- 只是提供简单的例子,所以未添加任何的css样式 -->
    <form action="Controller/method" method="post">
        <input type="text" name="name"/>
        <input type="submit" value="提交"/>
        <button type="submit">提交</button>
    </form>
    
    </body>
    </html>
    
    type = submit 与type = botton的区别

    当type = submit时,该点击发生后,就直接启动了form的提交,而type = botton时,只是表明了该标签是一个按钮,当发生点击时,form没有任何的反应

    2、带验证的提交

    2.1、onsubmit提交验证

    该提交方式中 input 或者 button 的type还是 submit类型的,但是在form 表元素里面需要加上 οnsubmit=“return check()”

    其中 check(),是我们用来做验证的函数,且前面必须加 return,否则无论我们的返回值是什么,表单就都将会提交,这样我们的验证函数就相当于名存实亡了

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>form表单提交</title>
    </head>
    <body>
    <!-- 只是提供简单的例子,所以未添加任何的css样式 -->
    <form action="Controller/method" method="post" onsubmit="return check()">
        <input type="text" name="name"/>
        <input type="submit" value="提交"/>
        <button type="submit">提交</button>
    </form>
    
    </body>
    <script type="text/javascript">
        function check() {
            if(){
                return true;    //return true; 时,表单将提交
            }
            else {
                return false;   //return false; 时,表单不提交
            }
        }
    </script>
    </html>
    

    上述提交的check函数中,我们可以对表单里面的数据进行判断或者验证,当验证结果是我们需要的,我们就可以返回true,将表单提交,如果是错误的,那么我们可以对表单做接下来的一些处理再 return true,或者干脆return false,做到不提交吗,这样就保证了我们数据的安全性,当数据不需要时,我们就不提交

    2.2、$(“form”).submit();

    该提交方式中 input 或者 button 的type则应该是button类型的,因为这样写就是为了做到验证,然后判断是否需要提交,如果写成了submit的话,就是变成无论如何都要提交了,将type=button,然后后给元素添加一个onclick事件,绑定函数,当在函数里面判断后,如果需要提交,则可以添加 $(“form”).submit(); 语句,表示需要提交了,如果不想提交,则将该语句规避就可以了

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>form表单提交</title>
        <script src="https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>
    </head>
    <body>
    <!-- 只是提供简单的例子,所以未添加任何的css样式 -->
    <form action="../../Controller/method" method="post">
        <input type="text" name="name"/>
        <input type="button" value="提交" onclick="check()">
        <button type="button" onclick="check()">提交</button>
    </form>
    
    </body>
    <script type="text/javascript">
        function check() {
            /**
             * 编写验证代码,若不想提交,就可以提前return;达到不提交
             */
            $("form").submit();
        }
    </script>
    </html>
    
    2.3 jQuery插件:Validation
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>form表单提交</title>
        <script src="https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>
        <script type="text/javascript" src="http://ajax.aspnetcdn.com/ajax/jquery.validate/1.10.0/jquery.validate.min.js"></script>
    </head>
    <body>
    <!-- 只是提供简单的例子,所以未添加任何的css样式 -->
    <form action="../../Controller/method" method="post">
        <input type="text" name="name"/>
        <input type="submit" value="提交">
        <button type="submit">提交</button>
    </form>
    
    </body>
    <script type="text/javascript">
        $(function () {
            $("form").validate({
            /**
           	 * 只是写一个例子,所以验证并没有给出
           	 */
                submitHandler:function (form){
                    /**
                     * 添加我们需要的验证信息
                     * 如果不需要提交,还是直接return就行了,规避form.submit();
                     */
                   form.submit();
                }
            });
        });
    </script>
    </html>
    

    使用该方法时,我们必须引入jQuery的插件(上述代码已给出),并且我们的 input 或者 button 的type则应该是submit类型的,否则不会响应,所谓的不会响应就是压根就不会执行submitHandler:function 下面的这个函数因为当表单验证成功并提交时执行,存在此方法时表单只能在此方法内部执行form.submit()才能提交,可理解成它替代了表单的onsubmit方法;,但是button在前面已经说过了,它并不是一个提交,而是表明它只是一个按钮而已,所有input 或者 button 的type则应该是submit类型的

    在submitHandler:function 函数的最后如果需要提交,执行的一定是form.submit();而不是$(“form”).submit();因为后者会造成一个死循环,因为上面解释过了,submitHandler:function 是在表单验证改成并且执行提交时才会执行,而$(“form”).submit();就是表单执行提交,所以每一次都执行提交,然后跳转submitHandler:function ,然后在该函数里面又执行了提交,所以就变成了一个死循环

    3、Ajax提交

    当我们需要提交一些数据,且想获取一些返回信息,且不想刷新页面时,就可以利用我们的Ajax的方式提交了

    3.1.1、表单插件jQuery.form.js 的 $(‘form’).ajaxSubmit({})方式

    该方式必须引入jQuery的表单插件,下面的是该表单插件的在线方式
    <script src=“https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js”></script>

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>form表单提交</title>
        <script src="https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>
        <script type="text/javascript" src="http://ajax.aspnetcdn.com/ajax/jquery.validate/1.10.0/jquery.validate.min.js"></script>
     $('form').ajaxSubmit({
    </head>
    <body>
    <!-- 只是提供简单的例子,所以未添加任何的css样式 -->
    <form action="../../Controller/method" method="post">
        <input type="text" name="name" value="form表单提交"/>
        <input type="button" value="提交" onclick="submitTest()"/>
        <button type="button" onclick="submitTest()">提交</button>
    </form>
    
    </body>
    <script type="text/javascript">
        function submitTest(){
            $('form').ajaxSubmit({
                url: $("from").attr("action"),
                type: $("from").attr("method"),
                dataType: 'json',
                beforeSubmit: function () {},
                success: function (result) {
                    /**
                     * 成功的回调函数
                     */
                },
                error:function(){
                    /**
                     * 失败的回调函数
                     */
                },
                clearForm: false,//禁止清楚表单
                resetForm: false //禁止重置表单
            });
        }
    </script>
    </html>
    

    这种方式是jQuery的插件Ajax提交,需要注意的是,input 和button的type都必须是button,然后给他们绑定一个事件函数,在函数里写上Ajax的提交,如果不是button而是submit的话,点击一次的按钮将会执行两次的提交,一次是form的自身提交,一次是Ajax的提交,所以type必须为button

    3.1.2、表单插件jQuery.form.js 的 $(‘form’).ajaxFrom({})方式
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>form表单提交</title>
        <script src="https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>
        <script type="text/javascript" src="http://ajax.aspnetcdn.com/ajax/jquery.validate/1.10.0/jquery.validate.min.js"></script>
        <script src="https://cdn.bootcss.com/jquery.form/4.2.1/jquery.form.min.js"></script>
    </head>
    <body>
    <!-- 只是提供简单的例子,所以未添加任何的css样式 -->
    <form action="../../Controller/method" method="post">
        <input type="text" name="name" value="form表单提交"/>
        <input type="submit" value="提交" onclick="submitTest()"/>
        <button type="submit" onclick="submitTest()">提交</button>
    </form>
    
    </body>
    <script type="text/javascript">
        function submitTest(){
            $('form').ajaxForm({
                url: $("from").attr("action"),
                type: $("from").attr("method"),
                dataType: 'json',
                beforeSubmit: function () {},
                success: function (result) {
                    /**
                     * 成功的回调函数
                     */
                },
                error:function(){
                    /**
                     * 失败的回调函数
                     */
                },
                clearForm: false,//禁止清楚表单
                resetForm: false //禁止重置表单
            });
        }
    </script>
    </html>
    

    这个和上面的代码几乎是一样的,区别就是 上面的是 $(‘form’).ajaxSubmit,而这个是 $(‘form’).ajaxForm,且上面的input 和button的type类型都是button的,而这个的input 和button的type类型都是submit,因为$(‘form’).ajaxForm不会自动提交,所以需要我们的form表单自己来提交,所以input 和button的type类型都必须是submit,否则点击将没有任何的反应

    3.2 、$.ajax({});方式
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>form表单提交</title>
        <script src="https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>
        <script type="text/javascript" src="http://ajax.aspnetcdn.com/ajax/jquery.validate/1.10.0/jquery.validate.min.js"></script>
    </head>
    <body>
    <!-- 只是提供简单的例子,所以未添加任何的css样式 -->
    <form action="../../Controller/method" method="post">
        <input type="text" name="name" value="form表单提交"/>
        <input type="button" value="提交" onclick="submitTest()"/>
        <button type="button" onclick="submitTest()">提交</button>
    </form>
    
    </body>
    <script type="text/javascript">
        function submitTest() {
            $.ajax({
                url: $("form").attr("action"),
                type: $("form").attr("method"),
                dataType: 'json',
                data: $("form").serialize(),
                success: function (result) {
                    /**
                     * 执行成功时,调用的回调函数
                     * 其中返回值result的类型由上面的dataType决定,像这就是一个json类型
                     */
                },
                error:function () {
                    /**
                     * 如果是异常,说明压根没有加入后台,在前台就炸了
                     * 提交异常时,执行error回调函数
                     */
                }
            });
        }
    </script>
    </html>
    

    这是一个较简单的Ajax方法,我们给按钮绑定一个事件函数,在函数里编写我们的ajax代码,但是需要注意的是,我们的 <input>和<button> 的type 必须为button,否则点击一次提交,我们的form表单将提交两次,一次是form自身的submit提交,一次是我们的Ajax提交,所以type不能为submit,只能是button

    这中方法,一定要在ajax里里面的 data:项里面添加我们需要向后台传输的数据,因为这种方式并没有和我们的form表单绑定,也就是说,如果没有写data,就相当于我们没有提交任何数据到达后台

    展开全文
  • Kafka学习笔记: 自动提交&手动提交.

    万次阅读 2019-12-26 23:22:20
    Consumer 需要向 Kafka 汇报自己的位移数据,这个汇报过程被称为提交位移(Committing Offsets)。因为 Consumer 能够同时消费多个分区的数据,所以位移的提交实际上是在分区粒度上进行的,即 Consumer 需要为分配给...

     

    Consumer 需要向 Kafka 汇报自己的位移数据,这个汇报过程被称为提交位移(Committing Offsets)。因为 Consumer 能够同时消费多个分区的数据,所以位移的提交实际上是在分区粒度上进行的,即 Consumer 需要为分配给它的每个分区提交各自的位移数据。

    提交位移主要是为了表征 Consumer 的消费进度,这样当 Consumer 发生故障重启之后,就能够从 Kafka 中读取之前提交的位移值,然后从相应的位移处继续消费,从而避免整个消费过程重来一遍。

    从用户的角度来说,位移提交分为自动提交和手动提交;从 Consumer 端的角度来说,位移提交分为同步提交和异步提交。

     

    自动提交代码

    
         Properties props = new Properties();
         props.put("bootstrap.servers", "localhost:9092");
         props.put("group.id", "test");
         props.put("enable.auto.commit", "true");
         props.put("auto.commit.interval.ms", "2000");
         props.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
         props.put("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
         KafkaConsumer<String, String> consumer = new KafkaConsumer<>(props);
         consumer.subscribe(Arrays.asList("foo", "bar"));
         while (true) {
             ConsumerRecords<String, String> records = consumer.poll(100);
             for (ConsumerRecord<String, String> record : records)
                 System.out.printf("offset = %d, key = %s, value = %s%n", record.offset(), record.key(), record.value());
         }

    一旦设置了 enable.auto.commit 为 true,Kafka 会保证在开始调用 poll 方法时,提交上次 poll 返回的所有消息。从顺序上来说,poll 方法的逻辑是先提交上一批消息的位移,再处理下一批消息,因此它能保证不出现消费丢失的情况。但自动提交位移的一个问题在于,它可能会出现重复消费。

    在默认情况下,Consumer 每 5 秒自动提交一次位移。我们假设提交位移之后的 3 秒发生了 Rebalance 操作。在 Rebalance 之后,所有 Consumer 从上一次提交的位移处继续消费,但该位移已经是 3 秒前的位移数据了,故在 Rebalance 发生前 3 秒消费的所有数据都要重新再消费一次。虽然你能够通过减少 auto.commit.interval.ms 的值来提高提交频率,但这么做只能缩小重复消费的时间窗口,不可能完全消除它。这是自动提交机制的一个缺陷。

     

    手动提交 KafkaConsumer#commitAsync()

    
    while (true) {
                ConsumerRecords<String, String> records =
                            consumer.poll(Duration.ofSeconds(1));
                process(records); // 处理消息
                try {
                            consumer.commitSync();
                } catch (CommitFailedException e) {
                            handle(e); // 处理提交失败异常
                }
    }

     

    commitAsync 不能够替代 commitSync .    commitAsync 的问题在于,出现问题时它不会自动重试。因为它是异步操作,倘若提交失败后自动重试,那么它重试时提交的位移值可能早已经“过期”或不是最新值了。因此,异步提交的重试其实没有意义,所以 commitAsync 是不会重试的。

     

    手动提交,我们需要将 commitSync 和 commitAsync 组合使用才能到达最理想的效果,原因有两个:

     

    1. 我们可以利用 commitSync 的自动重试来规避那些瞬时错误,比如网络的瞬时抖动,Broker 端 GC 等。因为这些问题都是短暂的,自动重试通常都会成功,因此,我们不想自己重试,而是希望 Kafka Consumer 帮我们做这件事。我们不希望程序总处于阻塞状态,影响 TPS。

    2. 我们不希望程序总处于阻塞状态,影响 TPS。

     

    同时使用了 commitSync() 和 commitAsync()

    
    try {
         while(true) {
              ConsumerRecords<String, String> records = 
                                        consumer.poll(Duration.ofSeconds(1));
              process(records); // 处理消息
              commitAysnc(); // 使用异步提交规避阻塞
         }
    } catch(Exception e) {
                handle(e); // 处理异常
    } finally {
        try {
            consumer.commitSync(); // 最后一次提交使用同步阻塞式提交
        } finally {
           consumer.close();
        }
    }

    对于常规性、阶段性的手动提交,我们调用 commitAsync() 避免程序阻塞,而在 Consumer 要关闭前,我们调用 commitSync() 方法执行同步阻塞式的位移提交,以确保 Consumer 关闭前能够保存正确的位移数据。将两者结合后,我们既实现了异步无阻塞式的位移管理,也确保了 Consumer 位移的正确性.

     

    Kafka Consumer API 为手动提交提供了这样的方法:commitSync(Map<TopicPartition, OffsetAndMetadata>) 和 commitAsync(Map<TopicPartition, OffsetAndMetadata>)。它们的参数是一个 Map 对象,键就是 TopicPartition,即消费的分区,而值是一个 OffsetAndMetadata 对象,保存的主要是位移数据。

     

    每处理 100 条消息就提交一次位移示例

    
    private Map<TopicPartition, OffsetAndMetadata> offsets = new HashMap<>();
    int count = 0;
    ……
    while (true) {
                ConsumerRecords<String, String> records = consumer.poll(Duration.ofSeconds(1));
                for (ConsumerRecord<String, String> record: records) {
                            process(record);  // 处理消息
                            offsets.put(new TopicPartition(record.topic(), record.partition()),
                                       new OffsetAndMetadata(record.offset() + 1);
                            if(count % 100 == 0)
                                        consumer.commitAsync(offsets, null); // 回调处理逻辑是null
                            count++;
                }
    }

    程序先是创建了一个 Map 对象,用于保存 Consumer 消费处理过程中要提交的分区位移,之后开始逐条处理消息,并构造要提交的位移值.

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     


    引用:

    Kafka核心技术与实战 - 胡夕


     

    展开全文
  • kafka 自动提交 和 手动提交

    千次阅读 2020-11-17 19:27:28
    Consumer 需要向 Kafka 汇报自己的位移数据,这个汇报过程被称为提交位移(Committing Offsets)。因为 Consumer 能够同时消费多个分区的数据,所以位移的提交实际上是在分区粒度上进行的,即 Consumer 需要为分配给...

    Consumer 需要向 Kafka 汇报自己的位移数据,这个汇报过程被称为提交位移(Committing Offsets)。因为 Consumer 能够同时消费多个分区的数据,所以位移的提交实际上是在分区粒度上进行的,即 Consumer 需要为分配给它的每个分区提交各自的位移数据。

    提交位移主要是为了表征 Consumer 的消费进度,这样当 Consumer 发生故障重启之后,就能够从 Kafka 中读取之前提交的位移值,然后从相应的位移处继续消费,从而避免整个消费过程重来一遍。

    从用户的角度来说,位移提交分为自动提交和手动提交;从 Consumer 端的角度来说,位移提交分为同步提交和异步提交。

    自动提交

    自动提交默认全部为同步提交

    自动提交相关参数

    • enable.auto.commit (bool) – 如果为True,将自动定时提交消费者offset。默认为True。
    • auto.commit.interval.ms(int) – 自动提交offset之间的间隔毫秒数。如果enable_auto_commit 为true,默认值为: 5000。

    当设置 enable.auto.commit 为 true,Kafka 会保证在开始调用 poll 方法时,提交上次 poll 返回的所有消息。从顺序上来说,poll 方法的逻辑是先提交上一批消息的位移,再处理下一批消息,因此它能保证不出现消费丢失的情况。

    网上有说

    自动提交位移的一个问题在于,它可能会出现重复消费。

    如果设置 enable.auto.commit 为 true,Consumer 按照 auto.commit.interval.ms设置的值(默认5秒)自动提交一次位移。我们假设提交位移之后的 3 秒发生了 Rebalance 操作。在 Rebalance 之后,所有 Consumer 从上一次提交的位移处继续消费,但该位移已经是 3 秒前的位移数据了,故在 Rebalance 发生前 3 秒消费的所有数据都要重新再消费一次。虽然你能够通过减少 auto.commit.interval.ms 的值来提高提交频率,但这么做只能缩小重复消费的时间窗口,不可能完全消除它。这是自动提交机制的一个缺陷。

    在实际测试中,未发现上述情况(kafka 版本 2.13), 而是会等待所有消费者消费完当前消息,或者等待消费者超时(等待过程中会报如下 warning), 之后才会 reblance。

    手动提交

    手动提交可以自己选择是同步提交(commitSync)还是异步提交(commitAsync )

    commitAsync 不能够替代 commitSync。commitAsync 的问题在于,出现问题时它不会自动重试。因为它是异步操作,倘若提交失败后自动重试,那么它重试时提交的位移值可能早已经“过期”或不是最新值了。因此,异步提交的重试其实没有意义,所以 commitAsync 是不会重试的。

    手动提交,我们需要将 commitSync 和 commitAsync 组合使用才能到达最理想的效果,原因有两个:

    1. 我们可以利用 commitSync 的自动重试来规避那些瞬时错误,比如网络的瞬时抖动,Broker 端 GC 等。因为这些问题都是短暂的,自动重试通常都会成功,因此,我们不想自己重试,而是希望 Kafka Consumer 帮我们做这件事。我们不希望程序总处于阻塞状态,影响 TPS。
    2. 我们不希望程序总处于阻塞状态,影响 TPS。

    同时使用 commitSync() 和 commitAsync()

    对于常规性、阶段性的手动提交,我们调用 commitAsync() 避免程序阻塞,而在 Consumer 要关闭前,我们调用 commitSync() 方法执行同步阻塞式的位移提交,以确保 Consumer 关闭前能够保存正确的位移数据。将两者结合后,我们既实现了异步无阻塞式的位移管理,也确保了 Consumer 位移的正确性.

    手动提交和自动提交中的 reblance 问题

    • 如果设置为手动提交,当集群满足 reblance 的条件时,集群会直接 reblance,不会等待所有消息被消费完,这会导致所有未被确认的消息会重新被消费,会出现重复消费的问题
    • 如果设置为自动提交,当集群满足 reblance 的条件时,集群不会马上 reblance,而是会等待所有消费者消费完当前消息,或者等待消费者超时(等待过程中会报如下 warning), 之后才会 reblance。

    python kafka-python 输出信息如下:

    [WARNING]Heartbeat failed for group scan_result because it is rebalancing

     kafka 中加入消费者时,kafka 会输出如下信息

    展开全文
  • 对分布式事务及两阶段提交、三阶段提交的理解 一、分布式数据一致性 在分布式系统中,为了保证数据的高可用,通常会将数据保留多个副本(replica),这些副本会放置在不同的物理的机器上。 1.什么是数据一致性 ...

    对分布式事务及两阶段提交、三阶段提交的理解

    一、分布式数据一致性

    在分布式系统中,为了保证数据的高可用,通常会将数据保留多个副本(replica),这些副本会放置在不同的物理的机器上。

    1.什么是数据一致性

    在数据有多份副本的情况下,如果网络、服务器或者软件出现故障,会导致部分副本写入成功,部分副本写入失败。这就造成各个副本之间的数据不一致,数据内容冲突,造成事实上的数据不一致。

    2.CAP定理

    CAP理论认为在分布式的环境下设计和部署系统时,有3个核心的需求:

    Consistency,Availability和Partition Tolerance,即CAP

    Consistency:一致性,这个和数据库ACID的一致性类似,但这里关注的所有数据节点上的数据一致性和正确性,而数据库的ACID关注的是在在一个事务内,对数据的一些约束。系统在执行过某项操作后仍然处于一致的状态。在分布式系统中,更新操作执行成功后所有的用户都应该读取到最新值。

    Availability:可用性,每一个操作总是能够在一定时间内返回结果。需要注意“一定时间”和“返回结果”。“一定时间”是指,系统结果必须在给定时间内返回。“返回结果”是指系统返回操作成功或失败的结果。

    Partition Tolerance:分区容忍性,是否可以对数据进行分区。这是考虑到性能和可伸缩性。

    3.数据一致性模型

    一些分布式系统通过复制数据来提高系统的可靠性和容错性,并且将数据的不同的副本存放在不同的机器。

    强一致性: 当更新操作完成之后,任何多个后续进程或者线程的访问都会返回最新的更新过的值。这种是对用户最友好的,就是用户上一次写什么,下一次就保证能读到什么。根据 CAP理论,这种实现需要牺牲可用性。

    弱一致性: 系统并不保证续进程或者线程的访问都会返回最新的更新过的值。用户读到某一操作对系统特定数据的更新需要一段时间,我们称这段时间为“不一致性窗口”。系统在数据写入成功之后,不承诺立即可以读到最新写入的值,也不会具体的承诺多久之后可以读到。

    最终一致性: 是弱一致性的一种特例。系统保证在没有后续更新的前提下,系统最终返回上一次更新操作的值。在没有故障发生的前提下,不一致窗口的时间主要受通信延迟,系统负载和复制副本的个数影响。DNS是一个典型的最终一致性系统。

    二、典型的分布式事务实例

    跨行转账问题是一个典型的分布式事务,用户A向B的一个转账1000,要进行A的余额-1000,B的余额+1000,显然必须保证这两个操作的事务性。 类似的还有,电商系统中,当有用户下单后,除了在订单表插入记,还要在商品表更新库存等,特别是随着微服务架构的流行,分布式事务的场景更变得更普遍。

    三、两阶段提交协议

    两阶段提交协议是协调所有分布式原子事务参与者,并决定提交或取消(回滚)的分布式算法。

    1.协议参与者

    在两阶段提交协议中,系统一般包含两类机器(或节点):一类为协调者(coordinator),通常一个系统中只有一个;另一类为事务参与者(participants,cohorts或workers),一般包含多个,在数据存储系统中可以理解为数据副本的个数。协议中假设每个节点都会记录写前日志(write-ahead log)并持久性存储,即使节点发生故障日志也不会丢失。协议中同时假设节点不会发生永久性故障而且任意两个节点都可以互相通信。

    这里写图片描述

    2.两个阶段的执行

    • 请求阶段(commit-request phase,或称表决阶段,voting phase) :在请求阶段,协调者将通知事务参与者准备提交或取消事务,然后进入表决过程。在表决过程中,参与者将告知协调者自己的决策:同意(事务参与者本地作业执行成功)或取消(本地作业执行故障)。

    • 提交阶段(commit phase) :在该阶段,协调者将基于第一个阶段的投票结果进行决策:提交或取消。 当且仅当所有的参与者同意提交事务协调者才通知所有的参与者提交事务,否则协调者将通知所有的参与者取消事务。参与者在接收到协调者发来的消息后将执行响应的操作。

    (3)两阶段提交的缺点

    • 同步阻塞问题:执行过程中,所有参与节点都是事务阻塞型的。当参与者占有公共资源时,其他第三方节点访问公共资源不得不处于阻塞状态。

    • 单点故障:由于协调者的重要性,一旦协调者发生故障。参与者会一直阻塞下去。尤其在第二阶段,协调者发生故障,那么所有的参与者还都处于锁定事务资源的状态中,而无法继续完成事务操作。(如果是协调者挂掉,可以重新选举一个协调者,但是无法解决因为协调者宕机导致的参与者处于阻塞状态的问题)

    • 数据不一致:在二阶段提交的阶段二中,当协调者向参与者发送commit请求之后,发生了局部网络异常或者在发送commit请求过程中协调者发生了故障,这回导致只有一部分参与者接受到了commit请求。而在这部分参与者接到commit请求之后就会执行commit操作。但是其他部分未接到commit请求的机器则无法执行事务提交。于是整个分布式系统便出现了数据部一致性的现象。

    (4)两阶段提交无法解决的问题

    当协调者出错,同时参与者也出错时,两阶段无法保证事务执行的完整性。考虑协调者再发出commit消息之后宕机,而唯一接收到这条消息的参与者同时也宕机了。那么即使协调者通过选举协议产生了新的协调者,这条事务的状态也是不确定的,没人知道事务是否被已经提交。

    四、三阶段提交协议

    三阶段提交协议在协调者和参与者中都引入超时机制,并且把两阶段提交协议的第一个阶段拆分成了两步:询问,然后再锁资源,最后真正提交。

    这里写图片描述

    (1)三个阶段的执行

    • CanCommit阶段: 3PC的CanCommit阶段其实和2PC的准备阶段很像。 协调者向参与者发送commit请求,参与者如果可以提交就返回Yes响应,否则返回No响应。
    • PreCommit阶段: Coordinator根据Cohort的反应情况来决定是否可以继续事务的PreCommit操作。 根据响应情况,有以下两种可能:

    A.假如Coordinator从所有的Cohort获得的反馈都是Yes响应,那么就会进行事务的预执行

    1. 发送预提交请求。Coordinator向Cohort发送PreCommit请求,并进入Prepared阶段。
    2. 事务预提交。Cohort接收到PreCommit请求后,会执行事务操作,并将undo和redo信息记录到事务日志中。
    3. 响应反馈。如果Cohort成功的执行了事务操作,则返回ACK响应,同时开始等待最终指令。

    B.假如有任何一个Cohort向Coordinator发送了No响应,或者等待超时之后,Coordinator都没有接到Cohort的响应,那么就中断事务:

    1. 发送中断请求。Coordinator向所有Cohort发送abort请求。
    2. 中断事务。Cohort收到来自Coordinator的abort请求之后(或超时之后,仍未收到Cohort的请求),执行事务的中断。
    • DoCommit阶段:该阶段进行真正的事务提交,也可以分为以下两种情况:

    执行提交

    1. 发送提交请求。Coordinator接收到Cohort发送的ACK响应,那么他将从预提交状态进入到提交状态。并向所有Cohort发送doCommit请求。
    2. 事务提交。Cohort接收到doCommit请求之后,执行正式的事务提交。并在完成事务提交之后释放所有事务资源。
    3. 响应反馈。事务提交完之后,向Coordinator发送ACK响应。
    4. 完成事务。Coordinator接收到所有Cohort的ACK响应之后,完成事务。

    中断事务

    Coordinator没有接收到Cohort发送的ACK响应(可能是接受者发送的不是ACK响应,也可能响应超时),那么就会执行中断事务。

    (2)三阶段提交协议和两阶段提交协议的不同

    对于协调者(Coordinator)和参与者(Cohort)都设置了超时机制(在2PC中,只有协调者拥有超时机制,即如果在一定时间内没有收到cohort的消息则默认失败)。在2PC的准备阶段和提交阶段之间,插入预提交阶段,使3PC拥有CanCommit、PreCommit、DoCommit三个阶段。PreCommit是一个缓冲,保证了在最后提交阶段之前各参与节点的状态是一致的。

    (3)三阶段提交协议的缺点

    如果进入PreCommit后,Coordinator发出的是abort请求,假设只有一个Cohort收到并进行了abort操作,而其他对于系统状态未知的Cohort会根据3PC选择继续Commit,此时系统状态发生不一致性。

    参考资料:

    维基百科:两阶段提交协议

    分布式协议之两阶段提交协议(2PC)和改进三阶段提交协议(3PC)

    关于分布式事务、两阶段提交协议、三阶提交协议

    Introduction to 3PC 三阶段提交协议简介

    原文链接:https://www.cnblogs.com/binyue/p/3678390.html

    展开全文
  • html5圆形进度条加载按钮是一款modernizr html5表单提交按钮圆形进度条加载动画表单验证效果。
  • 如何防止重复提交

    万次阅读 2019-06-20 09:50:39
    转载 如何防止重复提交 一、有很多的应用场景都会遇到重复提交问题,比如: 1、点击提交按钮两次。 2、点击刷新按钮。 3、使用浏览器后退按钮重复之前的操作,导致重复提交表单。 4、使用浏览器历史记录重复提交表单...
  • 正确理解二阶段提交(Two-Phase Commit)

    万次阅读 多人点赞 2019-03-07 15:42:56
    二阶段提交出现的背景是, 当我们使用分布式系统时, 如果分布式系统中的机器发生故障之后, 如何保证事务数据的一致性。 从一个场景入手, 假设一个人要从 A 银行向 B 银行进行跨行转账 100 元。 此时我们需要对 A ...
  • form表单提交的几种方式

    万次阅读 多人点赞 2019-06-04 09:41:03
    表单提交方式一:直接利用form表单提交 html页面代码: <!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title>Insert title here</title> </head> &...
  • asp.net在线作业提交管理系统

    热门讨论 2012-11-24 00:48:17
    asp.net在线作业提交管理系统,实现了学生在线作业的提交功能,主要提供了作业的在线提交,数据库是sqlsever 。
  • javaWeb应用后端防止表单重复提交

    万次阅读 2019-05-29 15:24:54
    正常我们防止一个页面的表单重复提交有2种途径 1:客户端控制(比如js判断,按钮置灰不可用等等这个大家自行网上查询) 2:服务器端针对api自己多业务逻辑判断 实际使用的场景中,我们大多是2者结合起来做,不能把...
  • 信息学奥赛一本通在线提交地址

    千次阅读 2018-12-25 21:51:54
    1.1.1 P1458 地球人口承载力估计 正确: 770 提交: 1794 比率: 42.92 % 1.1.2 P1686 Hello, World! 正确: 770 提交: 1646 比率: 46.78 % 1.1.3 P1687 输出第二个整数 正确: 850 提交: 1173 比率: 72.46 % 1.1.4 ...
  • 如何将项目提交到GitHub

    万次阅读 2018-06-05 11:00:06
    一、前言 GitHub这个平台相信大家都不陌生,并且你...那么应该如何将我们的项目提交到这个“高大上”的平台呢?请继续往下看。 二、项目的创建与提交 1.在本篇文章中,我不会教给你如何安装Git并配置相关的环...
  • form表单防止重复提交的N种方法

    千次阅读 2019-04-29 17:17:50
    Form表单重复提交是在多用户Web应用中最常见、带来很多麻烦的一个问题。有很多的应用场景都会遇到重复提交问题,比如: (1)点击提交按钮两次。 (2)点击刷新按钮。 (3)使用浏览器后退按钮重复之前的操作,导致重复...
  • 当页面上有表单的时候,为了防止用户等不及服务器端响应重复点击提交按钮向服务器端发送重复请求,我们通常需要在请求提交之前将提交按钮禁用。 先来看一下页面。 当用户点击提交申请这个按钮时,我们需要将其禁用...
  • 表单重复提交是在多用户Web应用中最常见、带来很多麻烦的一个问题。有很多的应用场景都会遇到重复提交问题,比如:点击提交按钮两次。点击刷新按钮。使用浏览器后退按钮重复之前的操作,导致重复提交表单。使用...
  • 表单提交-form提交和ajax提交

    万次阅读 2018-01-21 12:13:10
    安全性与提交文件的业务处理(格式检测,防注入)有关,与提交方式无关。 一般登录用表单提交,点击提交触发submit事件,一般会 使页面发生跳转,页面的跳转等行为的控制往往在后端,后端控制页面的跳转及数据的...
  • 如何使用git合并多次提交

    千次阅读 2020-01-18 13:17:36
    在为代码添加一个新功能的时候你会怎么做?(从git的操作顺序来说) 如果是我的话,顺序如下...但之后当你或者同事review代码,或者测试测出bug时,你又需要改代码并且将改后的代码提交,这样就造成了一个功能多次提...
  • SpringBoot如何防止重复提交

    万次阅读 2019-06-12 21:32:46
    场景:同一个用户在2秒内对同一URL的提交视为重复提交。 思考逻辑: 1.从数据库方面考虑,数据设计的时候,某些数据有没有唯一性,如果有唯一性,要考虑设置唯一索引,可以避免脏数据。 2.从应用层面考虑,首先...
  • git是我们代码管理必不可少的工具,平常我们使用时可能用遇到下面的问题,有时候我们提交代码后,发现提交错了,比如本地修改了不想提交的文件提交了上去,或者误提交了不完整的代码,这时候怎么把提交的回退呢?...
  • Flask表单提交的方法

    万次阅读 2018-04-19 18:01:27
    这里介绍一下Flask表单提交相关的方法,还是以代码实例为主。首先,Flask模板中表单提交代码与我们一般写的H5表单无异,当然,Flask也提供了表单类,Flask-WTF扩展。这里只介绍常规的表单提交方法。首先是模板类:&...
  • 解决表单重复提交的简单方法

    千次阅读 2018-07-26 16:38:47
    在平时开发中,如果网速比较慢的情况下,用户提交表单后,发现服务器半天都没有响应,那么用户可能会以为是自己没有提交表单,就会再点击提交按钮重复提交表单,我们在开发中必须防止表单重复提交。 一、表单重复...
  • 1.1.1撤销提交后又想恢复刚刚销毁的提交 1.2 撤销-但保留你的改动 1.3 最安全轻微的撤销 2.撤销已经推送到remote仓库的提交 2.1 利用git revert来撤销远程提交 本篇文章主要记录git reset 及 git revert 的使用...
  • kafka手动提交与自动提交

    千次阅读 2019-07-12 14:55:27
    kafka的提交分为手动提交和自动提交 自动提交: kafka: enable-auto-commit: ${KAFKA_CONSUMER_ENABLE_AUTO_COMMIT:true} 手动提交: enable-auto-commit: ${KAFKA_CONSUMER_ENABLE_AUTO_COMMIT:false} ...
  • SpringBoot手动提交事务

    万次阅读 2019-09-06 11:06:48
    有很多情况我们同一个方法需要多次提交事务:这个时候就不能使用Transactional注解,需要自动提交事务,因为我们项目整合的是jpa @Autowired private PlatformTransactionManager transactionManager; ...
  • 1. 为什么会出现表单重复提交问题? 网络延迟的情况下用户多次点击submit按钮导致表单重复提交 用户提交表单后,点击【刷新】按钮导致表单重复提交(点击浏览器的刷新按钮,就是把浏览器上次做的事情再做一次,因为...
  • 全面解决`Git`错误提交后该如何回滚操作?

    千次阅读 多人点赞 2020-08-20 20:10:46
    and git commit 将最新修改后的代码commit 则提交后的提交记录假设如下: 可以看到,我们错误提交的commit_id4提交记录消失,取而代之的是我们更新代码后提交的记录commit_id5; 这样就完成了本地的代码修改和更新 ...
  • Git提交代码 提交到分支上

    千次阅读 2020-05-18 18:01:20
    简单的代码提交流程 git status #查看工作区代码相对于暂存区的差别 git add . #将当前目录下修改的所有代码从工作区添加到暂存区 . 代表当前目录 add后面一个空格然后输入点 git commit -m #‘注释’ 将缓存区内容...
  • 分布式两阶段提交和三阶段提交

    万次阅读 多人点赞 2016-07-31 23:59:26
    随着大型网站的各种高并发访问、海量数据处理等场景越来越多,如何...本文主要介绍关于分布式事务,二阶段提交和三阶段提交。 在分布式系统中,为了保证数据的高可用,通常,我们会将数据保留多个副本(replica),这些
  • 防止表单重复提交(只通过后台实现)

    万次阅读 热门讨论 2019-03-26 18:15:18
    由于网速等原因造成页面卡顿,用户重复刷新提交页面。 黑客或恶意用户使用postman等工具重复恶意提交表单(攻击网站)。 这些情况都会导致表单重复提交,造成数据重复,增加服务器负载,严重甚至会造成服务器宕机...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,454,731
精华内容 981,892
关键字:

提交