时序数据库批量插入数据报错 返回

SqlSugar
50 265

image.png

定时程序,每分钟执行一次,批量插入数据时,有时候会报错,报错信息有以下两种

  1. 1.连接数据库过程中发生错误,检查服务器是否正常连接字符串是否正确,错误信息:Exception while reading from stream.

  2. 2.00000: table busy [reason=insert]

热忱回答50

  • Insertable插入单条数据记录时生成的语句是参数化的,插入批量数据记录时生成的是拼接的语句。

    这样有个问题,数据实体定义的double类型字段,在生成语句时会当字符串字段处理。时序数据库无法自动对数据类型进行转换,会报错:STRING->DOUBLE失败

    0 回复
  • @摇曳的风筝:局部代码看不出问题 你sqlsugarscope 为什么不是单例 


    STRING->DOUBLE失败 这个我可以修复

    0 回复
  • @fate sta:没有用单例是因为我想把数据同时插入三个数据库,写了个循环,我去掉循环用单例再试一下。

    0 回复
  • image.png



    image.png



    用了单例,还是会报错哎。


    image.png

    0 回复
  • CodeFirst不要写到业务里面

    0 回复
  • 在程序启动时调用

    0 回复
  • 还有try只是局部代码最上层怎么谳用的我看不到

    0 回复
  • @fate sta:因为不会自动创建表,所以加了InitTables,我去掉再试试。image.png

    0 回复
  • F12 Execute 看一下定义

    0 回复
  • image.png



    去掉InitTables还是一样的哎

    0 回复
  • 你先改成这样吧,用copynew可以解决错误的异步用法


     await db.CopyNew().Insertable(list)Userpaemter().ToListAsync();

    0 回复
  • 最新版本支持

    0 回复
  • @fate sta:是用的最新版,已经加了CopyNew,看看效果

    0 回复
  • @fate sta:还是报错了

    image.png

    0 回复
  • https://www.donet5.com/Home/Doc?typeId=2349

    0 回复
  • 换成这种写法试一下

    0 回复
  • @fate sta


    image.png




    image.png



    这样写的,还是会有报错的情况。



    微信图片_20220805221406.png



    0 回复
  • @摇曳的风筝:我的意思是用TaskWhenall按上面的链接写

    0 回复
  • 如果还有问题控制台提供完整用例

    0 回复
  • using SqlSugar;
    using System;
    using System.Linq;
    using System.Threading.Tasks;
    
    namespace OrmTest
    {
        class Program
        {
            static async Task Main(string[] args)
    
            {
    
                int max = 10000;
    
                Task[] tasks = new Task[max];
    
    
    
                for (int i = 0; i < max; i++)
                {
    
                    //SqlSugarScope 强制 new一个SugarClient
                    var db = SqlSugarHelper.Db.CopyNew(); //5.1.1版本支持(CopyNew)
    
                    tasks[i] = db.Insertable(new Order() {  CreateTime=DateTime.Now,
                     Name="a", Price=1})
                        .UseParameter().ExecuteCommandAsync();
    
                }
    
                await Task.WhenAll(tasks);
    
            }
    
        }
    
    
    
        //实体类   
        public class SqlSugarHelper
        {
    
    
    
            public static SqlSugarScope Db = new SqlSugarScope(new ConnectionConfig()
            {
                ConnectionString =Config.ConnectionString,//连接符字串
                DbType = DbType.QuestDB,//数据库类型
                IsAutoCloseConnection = true //不设成true要手动close
            },
           db => {
               db.Aop.OnLogExecuting = (s, z) =>
               {
                   Console.WriteLine(s);
               };
           });
        }
    }

    完整用例

    0 回复
  • @fate sta

    真尴尬,我发现报错是因为公司的电脑磁盘太烂了,程序跑起来就100%磁盘占用率,用家里电脑就一切正常了

    0 回复
  • @摇曳的风筝:可能是电脑用了VPN影响的,目前我发现过这种情况

    0 回复
  • @fate sta:把电脑上的程序和服务都关了一些,磁盘占用还是100%,至少可以确定不是程序问题了

    0 回复
  • @fate staimage.png

    0 回复
  • @fate staimage.png





    不知道为啥,有600w数据的时候,会一直报这个错误,数据少的时候运行正常。

    0 回复
  • @fate staimage.png


    意思是不能多线程写入数据?

    0 回复
  • @fate staimage.png

    0 回复
  • @fate sta:建议增加重试机制,可以结合polly。

    image.png

    0 回复
  • @摇曳的风筝:我这边测试正常,你可以提供用例,如果个别服务器,先手动处理吧

    0 回复
  • 你可以拿我上面的用例进行修改

    0 回复
  • 后续我会封装一个 http insert来处理大数据, 这个比较快

    0 回复
  • -

    0 回复
  • @fate sta:数据量小的时候是正常的,当表里有几百万数据的时候,每次插入几百到上千条记录时会报table busy。完整测试代码:

    链接:https://pan.baidu.com/s/1ztn_g10l5NlFtksNtmBECA?pwd=u2uw 

    提取码:u2uw 

    --来自百度网盘超级会员V4的分享


    0 回复
  • @fate sta:我现在用polly自动重试,可以处理插入失败的问题。

    0 回复
  • @摇曳的风筝: 我看一下

    0 回复
  • @摇曳的风筝polly自动重试 你代码怎么写的

    0 回复
  • 今天我这边出一个HTTP方式插入,这个性能更快,晚点发布,会更新到文档

    0 回复
  • @fate sta:polly用着很简单,Execute的参数就是你要重试的方法,QBDException是自定义的异常类型,重试方法的异常需要用相同的异常类型来捕获,当然也可以用Exception对所有异常进行捕获和重试。我发现写入速度慢是因为我的数据data_time时间间隔很大,且没有顺序。因为数据是从别人接口获取的,理论上是按照当前时间每分钟一条的,没想到居然是乱的,于是换了upload_time时间来做分区键,写入速度就快多了。

    image.png

    0 回复
  • @fate sta

    参数化的语句,没有处理datetime类型需要转时间戳的问题。昨天好像没这个问题的,今天更新了最新版就有了。

    E4_{SR6FVA0VKA[QM}95YJ4.png




    A$39(G}8C)A%@]KRY)QQQ1Z.png



    0 回复
  • @摇曳的风筝:和更新没关系,昨天是单条插入,你这个是批量插入

    0 回复
  • 代码没有错,提供完整用例

    0 回复
  • 源码DEMO是可以跑的

    0 回复
  • 你这个插入没用UsePrameter

    0 回复
  • @fate sta:昨天有个错误是因为时间类型为空导致的,我以为是datetime没有转换导致的,现在看是bool类型的参数写入失败了

    image.png


    image.png

    0 回复
  • @fate sta

    HTTP API的方式nuget已经更新了吧,但是貌似文档没有更新啊

    0 回复
  • @摇曳的风筝:那种方式有点问题,还是等QuestDb本身去完善吧  ,BOOL类型什么样情况下有问题

    0 回复
  • @fate sta:批量插入的时候我看生成的语句就是直接插入true或者false,这样的语句是可以执行成功的,但是这种参数化的语句就不行了。

    0 回复
  • @fate sta

    1660368653518.png

    0 回复
  • @摇曳的风筝

    请升级到5.1.2.1已经修复

    0 回复
  • @fate sta:搞定了

    0 回复