NewLife.XCode是一个有10多年历史的开源数据中间件,支持nfx/netstandard,由新生命团队(2002~2019)开发完成并维护至今,以下简称XCode。

整个系列教程会大量结合示例代码和运行日志来进行深入分析,蕴含多年开发经验于其中,代表作有百亿级大数据实时计算项目。

开源地址:https://github.com/NewLifeX/X(求star, 729+)

累加的需求背景

一个网站,部署了两台应用服务器,共用数据库,其中文章表有个访问次数的字段。

现在需要记录访问次数,需要怎么做?

var entity = Article.FindByID();
entity.Views++;
entity.Update();

如果两台服务器都有用户访问了9527这篇文章,访问前Views是1000,访问后是多少?1002?大部分情况下是1002,少数情况下可能是1001。

如果每台服务器都有100个用户同时访问这篇文章呢?那可就精彩了,最后访问数可能是1001到1200之间的某个数。

按照教科书做法,我们似乎应该开个事务加个锁,确保同时只能有一个用户(线程)修改这一行数据。

且不说加锁和事务成本有多高,光是为了一个字段就锁住这一行导致用户无法更新这一行其它字段,就让人觉得挺不地道的。再者,访问次数对于其它字段来说,也许并没有那么重要。

聪明如你,可以想到这么一个办法:

update article set views=views+1 where id=9527

哈,这就是XCode增量累加的出发点,每个用户(线程)执行自己的那一次,不管排队先后,最终结果都将会是1200。

设置增量累加

在实体类静态构造函数中,可以设置需要增量累加的字段

Meta.Factory.AdditionalFields 添加需要采用增量累加的字段,执行update时才生成 x=x+123 样子的语句。

测试代码:

Update VisitStat Set Times=Times+123,Users=Users+1,IPs=IPs+1,UpdateTime='2019-03-26 22:36:14' Where ID=1

从输出效果看到,产生了累加效果。并且,这段代码不管执行多少次,都是这样的累加效果,而不管实际值是多少。

累加原理

从数据库查出来一个对象时,如果发现有设置累加字段,XCode会把此时的数据“备份” 下来

在执行update保存的时候,拿累加字段的最后值减去原始备份值,得到差值(可能是负数),生成 x=x+123 或 x=x-456 的语句。

不光整数,小数也可以设置累加字段。

需要注意的是,如果字段x允许空,并且要更新行的x字段刚好为NULL,x=x+123 将会得不到预期效果。

高级用法

再看开头的例子,即使使用了累加,不需要加锁以及开事务,仍然需要update数据库200次。

借助累加以及异步保存功能,可以把这个次数大大降低。

var entity = Article.FindByID(9527);
entity.Views++;
entity.SaveAsync(5_000);

先把Views设为累加字段。

Article.FindByID内部可以用对象缓存,然后每台应用服务器在10秒(默认缓存时间)内多线程查到的都是同一个entity对象。

SaveAsync将把对象entity放入实体队列,5秒后延迟保存。如果200用户访问集中在5秒内,最后每台服务器只会执行一次update操作。

Update Article Set Viewss=Views+100 Where ID=9527

数据库写入次数由200次下降到2次,提升100倍。

由此,你能想到什么更有意思的用法了吗?

系列教程

NewLife.XCode教程系列[2019版]

  1. 增删改查入门。快速展现用法,代码配置连接字符串
  2. 数据模型文件。建立表格字段和索引,名字以及数据类型规范,推荐字段(时间,用户,IP)
  3. 实体类详解。数据类业务类,泛型基类,接口
  4. 功能设置。连接字符串,调试开关,SQL日志,慢日志,参数化,执行超时。代码与配置文件设置,连接字符串局部设置
  5. 反向工程。自动建立数据库数据表
  6. 数据初始化。InitData写入初始化数据
  7. 高级增删改。重载拦截,自增字段,Valid验证,实体模型(时间,用户,IP)
  8. 脏数据。如何产生,怎么利用
  9. 增量累加。高并发统计
  10. 事务处理。单表和多表,不同连接,多种写法
  11. 扩展属性。多表关联,Map映射
  12. 高级查询。复杂条件,分页,自定义扩展FieldItem,查总记录数,查汇总统计
  13. 数据层缓存。Sql缓存,更新机制
  14. 实体缓存。全表整理缓存,更新机制
  15. 对象缓存。字典缓存,适用用户等数据较多场景。
  16. 百亿级性能。字段精炼,索引完备,合理查询,充分利用缓存
  17. 实体工厂。元数据,通用处理程序
  18. 角色权限。Membership
  19. 导入导出。Xml,Json,二进制,网络或文件
  20. 分表分库。常见拆分逻辑
  21. 高级统计。聚合统计,分组统计
  22. 批量写入。批量插入,批量Upsert,异步保存
  23. 实体队列。写入级缓存,提升性能。
  24. 备份同步。备份数据,恢复数据,同步数据
  25. 数据服务。提供RPC接口服务,远程执行查询,例如SQLite网络版
  26. 大数据分析。ETL抽取,调度计算处理,结果持久化

[NewLife.XCode]增量累加的更多相关文章

  1. [NewLife.XCode]对象字典缓存(百万军中取敌首级)

    NewLife.XCode是一个有10多年历史的开源数据中间件,支持nfx/netcore,由新生命团队(2002~2019)开发完成并维护至今,以下简称XCode. 整个系列教程会大量结合示例代码和 ...

  2. [NewLife.XCode]高级增删改

    NewLife.XCode是一个有10多年历史的开源数据中间件,支持nfx/netstandard,由新生命团队(2002~2019)开发完成并维护至今,以下简称XCode. 整个系列教程会大量结合示 ...

  3. [NewLife.XCode]实体列表缓存(最土的方法实现百万级性能)

    NewLife.XCode是一个有10多年历史的开源数据中间件,支持nfx/netcore,由新生命团队(2002~2019)开发完成并维护至今,以下简称XCode. 整个系列教程会大量结合示例代码和 ...

  4. [NewLife.XCode]增删改查入门

    NewLife.XCode是一个有10多年历史的开源数据中间件,由新生命团队(2002~2019)开发完成并维护至今,以下简称XCode. 整个系列教程会大量结合示例代码和运行日志来进行深入分析,蕴含 ...

  5. [NewLife.XCode]数据模型文件

    NewLife.XCode是一个有10多年历史的开源数据中间件,由新生命团队(2002~2019)开发完成并维护至今,以下简称XCode. 整个系列教程会大量结合示例代码和运行日志来进行深入分析,蕴含 ...

  6. [NewLife.XCode]实体类详解

    NewLife.XCode是一个有10多年历史的开源数据中间件,由新生命团队(2002~2019)开发完成并维护至今,以下简称XCode. 整个系列教程会大量结合示例代码和运行日志来进行深入分析,蕴含 ...

  7. [NewLife.XCode]功能设置

    NewLife.XCode是一个有10多年历史的开源数据中间件,由新生命团队(2002~2019)开发完成并维护至今,以下简称XCode. 整个系列教程会大量结合示例代码和运行日志来进行深入分析,蕴含 ...

  8. [NewLife.XCode]反向工程(自动建表建库大杀器)

    NewLife.XCode是一个有10多年历史的开源数据中间件,支持nfx/netstandard,由新生命团队(2002~2019)开发完成并维护至今,以下简称XCode. 整个系列教程会大量结合示 ...

  9. [NewLife.XCode]数据初始化

    NewLife.XCode是一个有10多年历史的开源数据中间件,支持nfx/netstandard,由新生命团队(2002~2019)开发完成并维护至今,以下简称XCode. 整个系列教程会大量结合示 ...

随机推荐

  1. 20175316盛茂淞 2018-2019-2 《Java程序设计》第8周学习总结

    20175316盛茂淞 2018-2019-2 <Java程序设计>第8周学习总结 教材学习内容总结 第十五章 泛型 -- 主要目的是可以建立具有类型安全的集合框架,如链表.散列映射等数据 ...

  2. 安装rabbtimq CentOS 7

    朋友们 今天安装rabbtimq  在安装完以后就是一直报错.一直启动不起来了.最后看到别人写到.centos 7  与 centos 6.下载的rabbitmq是不一样的. https://dl.b ...

  3. php hash_file

    string hash_file ( string $algo , string $filename [, bool $raw_output = FALSE ] ) 参数¶ algo 要使用的哈希算法 ...

  4. [转]ps命令详解

    原文地址:http://apps.hi.baidu.com/share/detail/32573968 转载自:http://www.cnblogs.com/wangkangluo1/archive/ ...

  5. Core Expression

    https://docs.oracle.com/cd/E12058_01/doc/doc.1014/e12030/cron_expressions.htm A Cron Expressions Cro ...

  6. OC协议、代理的简单使用

    在不同类之间传递数据,我所学到的有三种,1.代理,2.block,3.通知.在这里,我们先来讲一下代理的使用,后面我会继续讲到block和通知.代理通常和协议是一起使用的,协议通常写在代理类里面,被代 ...

  7. View事件分发

    NOTE: 笔记,碎片式内容 控件 App界面的开主要就是使用View,或者称为控件.View既绘制内容又响应输入,输入事件主要就是触摸事件. ViewTree 控件基类为View,而ViewGrou ...

  8. 64位 windows10,MYSQL8.0.13重置密码(忘记密码或者无法登录)

    上一节的MySQL的配置安装里,并没有用到配置文件my.ini.那在MYSQL8.0.13如何解决密码重置问题呢.我去网上搜了好多的资料都是改配置文件my.ini的,后来终于找到了一条命令:操作步骤如 ...

  9. Maven 项目打包出现错误 Failed to execute goal org.apache.maven.plugins:maven-resources-plugin

    今天碰到一个奇怪的问题,就是我在eclipse中使用maven命令:clean package 命令打完包之后,通过FlashFXP将jar包上传到Linux服务器后,由于其他原因,我想要修改下程序重 ...

  10. SpringMVC框架六:拦截器

    拦截器的概念就不介绍了: SpringMVC中拦截器的执行规则: 一个小示例展示: 我搞两个拦截器: 第一个: package org.dreamtech.springmvc.interceptor; ...