简体   繁体   English

MongoDB 4.0和SpringData中的事务

[英]Transactions in MongoDB 4.0 and SpringData

I'm developing an application that reads a file that contains just text data. 我正在开发一个读取仅包含文本数据的文件的应用程序。 Some times, this files are small (around 500kb~1mb) but some times the file size can be 5bm~20mb. 有时,此文件很小(大约500kb〜1mb),但有时文件大小可能是5bm〜20mb。 I need to make sure that all the data in the files is stored in the database, so the transactions come in. 我需要确保文件中的所有数据都存储在数据库中,以便进行事务处理。

Each line of the file represents information that will be validated and stored in that database. 文件的每一行代表将被验证并存储在该数据库中的信息。 If an error occurs in this process, the transaction is aborted. 如果在此过程中发生错误,则事务将中止。

My file import process needs to be as follows: 我的文件导入过程需要如下:

Import Function 导入功能

@Transactional
public void importFile(MultipartFile multipartFile) throws IOException, IllegalAccessException, NoSuchFieldException {
    try (BufferedReader file = new BufferedReader(new InputStreamReader(multipartFile.getInputStream()))) {
        this.validateFile(file);
    }

    try (BufferedReader arquivo = new BufferedReader(new InputStreamReader(multipartFile.getInputStream()))) {
        String line = file.readLine();

        ValidHeader validHeader = this.validHeaderService.toParse(line.split(","));
        this.validHeaderService.save(validHeader);

        while ((line = file.readLine()) != null)
            this.importFileContent(linha.split(",")); // -> This will validade and save others file content.
    }
}

ValidHeader.java ValidHeader.java

@Document(collection = "ValidHeader")
public class ValidHeader {

    @Id
    private ObjectId id;

    @Enumerated(EnumType.STRING)
    private TipoRegistro tipoRegistro;

    private int pontoVenda;

    //Constructor & getters & setters

}

For small files the transactions works fine, but my problem is for large files. 对于小文件,事务工作正常,但是我的问题是大文件。

org.springframework.data.mongodb.UncategorizedMongoDbException: Command failed with error 251 (NoSuchTransaction): 'Transaction 1 has been aborted.' on server localhost:27017.

But debugging I realized that the main problem was 但是调试后我意识到主要问题是

com.mongodb.MongoCommandException: Command failed with error 257 (TransactionTooLarge): 'Total size of all transaction operations must be less than 16793600. Actual size is 16794367' on server localhost:27017

From what I understand, Mongo interprets the entire transaction scope as a single document, why does it do this? 据我了解,Mongo将整个交易范围解释为一个文档,为什么这样做呢? and how can I solve these problems? 以及如何解决这些问题?

--ADTIONAL INFORMATION-- -附加信息-

SpringDataMongo: 2.1.0.M3
MongoJavaDriver: 3.8
HibernateOgmMongoDb: 5.3.1.Final

I do not understand of MongoDB but why you persist each line from the file? 我不了解MongoDB,但为什么要保留文件中的每一行? Can you first read the whole file and after that persist it? 您可以先读取整个文件,然后再将其保存吗? Now you make transaction for each line and this is most probably not right. 现在您为每一行进行交易,这很可能是不正确的。 Yes you will have 20 mb in the memory at one time but that why we are using computers with gigabytes of ram. 是的,您一次将拥有20 mb的内存,但这就是为什么我们使用的是千兆字节ram的计算机。 :) If you get out of memory for example you have 20 GB files then you can split them on chunks and persist them one by one. :)例如,如果内存不足,则有20 GB的文件,则可以将它们拆分为多个块,然后逐一保留。

Just to see how this will impact your code first make StringBuilder. 只是为了了解这将如何影响您的代码,首先创建StringBuilder。 Then in your while look append all of the lines. 然后,在您的同时查看所有行。 After the while then your your method for persisting into the database 片刻之后,您的持久化到数据库的方法

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM