From b8bf67e2b8e855ebc38fc7c11b98fd324b756f18 Mon Sep 17 00:00:00 2001 From: dankito Date: Tue, 28 Apr 2020 17:13:17 +0200 Subject: [PATCH] Fixed that on concurrent call to saveOrUpdateAccountTransactions() two DocumentsWriter try to write to same directory --- .../persistence/LuceneBankingPersistence.kt | 44 +++++++++++++++---- 1 file changed, 36 insertions(+), 8 deletions(-) diff --git a/persistence/LuceneBankingPersistence/src/main/kotlin/net/dankito/banking/persistence/LuceneBankingPersistence.kt b/persistence/LuceneBankingPersistence/src/main/kotlin/net/dankito/banking/persistence/LuceneBankingPersistence.kt index 5596a417..e513f312 100644 --- a/persistence/LuceneBankingPersistence/src/main/kotlin/net/dankito/banking/persistence/LuceneBankingPersistence.kt +++ b/persistence/LuceneBankingPersistence/src/main/kotlin/net/dankito/banking/persistence/LuceneBankingPersistence.kt @@ -8,7 +8,6 @@ import net.dankito.banking.LuceneConfig.Companion.BookingDateFieldName import net.dankito.banking.LuceneConfig.Companion.BookingDateSortFieldName import net.dankito.banking.LuceneConfig.Companion.BookingTextFieldName import net.dankito.banking.LuceneConfig.Companion.CurrencyFieldName -import net.dankito.banking.LuceneConfig.Companion.IdFieldName import net.dankito.banking.LuceneConfig.Companion.OtherPartyAccountIdFieldName import net.dankito.banking.LuceneConfig.Companion.OtherPartyBankCodeFieldName import net.dankito.banking.LuceneConfig.Companion.OtherPartyNameFieldName @@ -21,6 +20,7 @@ import net.dankito.utils.serialization.ISerializer import net.dankito.utils.serialization.JacksonJsonSerializer import org.apache.lucene.index.IndexableField import java.io.File +import java.util.concurrent.atomic.AtomicInteger open class LuceneBankingPersistence( @@ -32,17 +32,24 @@ open class LuceneBankingPersistence( protected val fields = FieldBuilder() + protected var documentsWriter: DocumentsWriter? = null + + protected val countWriterUsages = AtomicInteger(0) + override fun saveOrUpdateAccountTransactions(bankAccount: BankAccount, transactions: List) { - DocumentsWriter(LuceneConfig.getAccountTransactionsIndexFolder(indexFolder)).use { writer -> - transactions.forEach { transaction -> - writer.updateDocumentForNonNullFields(IdFieldName, transaction.id, - *createFieldsForAccountTransaction(bankAccount, transaction).toTypedArray() - ) - } + val writer = getWriter() - writer.flushChangesToDisk() + transactions.forEach { transaction -> + writer.updateDocumentForNonNullFields( + LuceneConfig.IdFieldName, transaction.id, + *createFieldsForAccountTransaction(bankAccount, transaction).toTypedArray() + ) } + + writer.flushChangesToDisk() + + releaseWriter() } protected open fun createFieldsForAccountTransaction(bankAccount: BankAccount, transaction: AccountTransaction): List { @@ -63,4 +70,25 @@ open class LuceneBankingPersistence( ) } + + @Synchronized + protected open fun getWriter(): DocumentsWriter { + countWriterUsages.incrementAndGet() + + documentsWriter?.let { return it } + + documentsWriter = DocumentsWriter(LuceneConfig.getAccountTransactionsIndexFolder(indexFolder)) + + return documentsWriter!! + } + + @Synchronized + protected open fun releaseWriter() { + val countUsages = countWriterUsages.decrementAndGet() + + if (countUsages == 0) { + documentsWriter?.close() + } + } + } \ No newline at end of file