项目放到服务器上,存入数据库报错

本地测试的时候成功了,可以存入数据库,一放到服务器上就报错了

img

img

问题就出在你打了码的那一行mtsql连接上,要么你写错了什么,要么服务器配置有问题

mysql能正常连接么,重启一下服务看看?

  • 这个问题的回答你可以参考下: https://ask.csdn.net/questions/7633575
  • 我还给你找了一篇非常好的博客,你可以看看是否有帮助,链接:将本地数据库中的数据上传到云服务器数据库
  • 除此之外, 这篇博客: 你的香腮边轻轻滑落的, 是你的泪,还是我的泪。中的 3.读取当地磁盘文件,多线程批量入库 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
  • 1.从磁盘扫描所有的文件,放入队列
    LinkedBlockingQueue fileQueue = new LinkedBlockingQueue(32);
    fileQueue.put(fileNamelist);

    2.开多线程处理队列中的文件
    public void handle(int threadNum){
    //开多线程处理队列中的文件
    ExecutorService fixedThreadPool = Executors.newFixedThreadPool(threadNum);
    for(int i=0;i<threadNum;i++){
    if(getFileQueue() == null){
    break;
    }else {
    fixedThreadPool.execute(new InsertThread(getFileQueue()));
    }
    }
    fixedThreadPool.shutdown();
    while (!fixedThreadPool.isTerminated()){
    try {
    Thread.sleep(1000);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    }

    3. InsertThread里run方法具体实现:
    while(true){
    PreparedStatement pstmt = null;
    String path=fileQueue.poll();
    if(pathnull){
    //队列为空了,则线程退出
    break;
    }
    //TODO读取文件,入库
    File file = new File(path);
    InputStreamReader isr = new InputStreamReader(new FileInputStream(file), “utf8”);
    BufferedReader bw = new BufferedReader(isr);
    String line = null;
    connection =
    DBUtil.getInstance().getLocalConnection(“jdbc:mysql://localhost:3306”,“acctbd”,“root”,“root”);
    String sql = “replace into " + “acct_item_20c” + " (” + “ACCT_ITEM_ID,ACCT_ID,ACCT_ITEM_TYPE_ID,AMOUNT,BILL_ID,BILLING_CYCLE_ID,” +
    “CREATE_DATE,CUST_ID,FEE_CYCLE_ID,GRP_ACCT_ITEM_TYPE_NBR,HAD_INVOICE_AMOUNT,ITEM_SOURCE_ID,NO_INVOICE_AMOUNT,OFFER_INST_ID” +
    “,ORI_ACCT_ITEM_ID,ONE_ACCT_ITEM_ID,PAY_CYCLE_ID,PAYMENT_METHOD,PRESENT_AMOUNT,PROD_INST_ID,STATUS_CD,STATUS_DATE,REGION_ID,” +
    “PARTNER_ID,BILL_XCHG_ID,PRD_ID,OFFER_ID,UNSURE_INCOME,EVENT_PRICING_STRATEGY_ID,LATN_ID,PLATFORM,card_flag)” + " values " +
    “(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)”;
    pstmt = connection.prepareStatement(sql);
    //这两个变量作为批量入库的判定标识
    int idx=1;
    int leftIdx=0;
    while((line = bw.readLine()) != null){
    if(“null”.equals(arr[4]) || StringUtils.isBlank(arr[4])){
    pstmt.setNull(5,Types.DECIMAL);
    }else {
    pstmt.setBigDecimal(5,new BigDecimal(arr[4]));
    }

    pstmt.addBatch();
    //N条提交一次
    if(idx%1000
    0){
    pstmt.executeBatch();
    //删除批次
    pstmt.clearBatch();
    //connection.commit();
    //剩余量设置为0
    leftIdx=0;
    }else{
    leftIdx++;
    }
    idx++;
    }
    //最后再做一次检测
    if (leftIdx>0){
    pstmt.executeBatch();
    //删除批次
    pstmt.clearBatch();
    //connection.commit();
    }
    bw.close();
    }
    }
    这里涉及到几个问题要注意下:
    1.两个过程可以同时进行,边读边写提升效率。
    2. 源生的jdbc塞一个null值,不是空,是一个为字符串的null值。还有字段设置为可以为null值的字段,要进行判断,要严谨。
    if(“null”.equals(arr[4]) || StringUtils.isBlank(arr[4])){
    pstmt.setNull(5,Types.DECIMAL);
    }else {
    pstmt.setBigDecimal(5,new BigDecimal(arr[4]));
    }
    3.批量提交的时候,要考虑每一种发生的情况,使性能最大化。
    4.插库如表的时候 replace into 用于这个表的主键有自增。还有Ingore 方法也可以具体没试。
    5.这里如果想知道成功插入了多少条,异常了多少条。方法具体如下:
    public AtomicLong dataRecord;定义一个AtomicLong类型的变量,
    while((line = bw.readLine()) != null){
    dataRecord20C.incrementAndGet();
    添加数据方法…
    }

        AtomicLong dataRecord20C=new AtomicLong();
        AtomicLong dataRecord20P=new AtomicLong();
        AtomicLong dataRecordBalance=new AtomicLong();
        long startInsert=System.currentTimeMillis();
        ExecutorService fixedThreadPool = Executors.newFixedThreadPool(insertThreadNum);
        for(int i=0;i<insertThreadNum;i++){
                fixedThreadPool.execute(new InsertThread(fileQueue, latnId, billingCycle,dataRecord20C,dataRecord20P,dataRecordBalance));
        }
        fixedThreadPool.shutdown();
        while (!fixedThreadPool.isTerminated()){
            try {
                Thread.sleep(1000*60);
                logger.info("has insert 20C RECORDS [{}],20P RECORDS [{}],BALANCE RECORDS [{}]",dataRecord20C,dataRecord20P,dataRecordBalance);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    

    6.读取数据库的数据时,如果数据量很多千万级别的,千万注意防止GC挂机问题。因为数据量过大,resultSet集肯定很大,所以要给予一定的限制,可以加上这几句。
    preparedStatement = conn.prepareStatement(sql,resultSet.TYPE_FORWARD_ONLY,resultSet.CONCUR_READ_ONLY);
    //执行sql前,添加这两句
    preparedStatement.setFetchSize(Integer.MIN_VALUE);
    preparedStatement.setFetchDirection(ResultSet.FETCH_REVERSE);
    resultSet = preparedStatement.executeQuery();

    Ok Fine ~

  • 您还可以看一下 李月喜老师的企业微信开发第三方应用开发篇课程中的 回调服务概述,内网穿透配置支持回调路由到本地小节, 巩固相关知识点
  • 以下回答由chatgpt基于相关博客总结生成:

    针对问题:项目在服务器上存入数据库时报错,可以有以下可能原因和解决方案:

    1. 数据库连接配置问题: 可以检查服务器和本地的数据库连接配置是否相同,确认用户名、密码、数据库名称、数据库地址、端口等连接信息是否正确。也可以检查服务器上的防火墙和网络是否有限制数据库连接。如果数据库连接配置正确,可以使用 telnet 命令测试服务器能否连接到数据库服务器。

    2. 数据库版本不兼容问题: 可以检查服务器和本地使用的数据库版本是否一致,有可能使用不同版本的数据库导致存储数据失败。如果版本不一致,可以升级或降级数据库版本,以确保一致性。

    3. 数据库表结构不一致问题: 可以检查服务器和本地的数据库表结构是否一致,有可能使用不同的表结构导致存储数据失败。可以使用工具比对两个数据库的表结构,确认表结构一致性。

    4. 数据库权限不足问题: 可以检查服务器和本地的数据库用户权限是否一致,有可能没有足够的权限存储数据到服务器上的数据库中。可以尝试使用授予更高权限的用户进行存储数据的操作。

    5. 数据库存储空间不足问题: 可以检查服务器上的数据库存储空间是否足够,有可能数据库存储空间已满导致存储数据失败。可以使用数据库管理工具查看数据库的存储空间使用情况,如果空间不足可以调整数据库存储空间大小或删除无用数据以释放空间。

    如果以上解决方案都不能解决问题,可以搜索相关错误信息或查看服务器端的日志文件来获取更多信息,以帮助定位问题。最终可以考虑寻求数据库专家的帮助,进行更深入的排查和调试。


- 检查你本地数据库  是否指向线上的数据库地址

- 检查 线上数据库地址 是否和你本地 配置文件中一致

- 你是要部署到服务器需要 把你本地连接的数据库地址的 配置文件改为你线上数据库地址