Fixed that on concurrent call to saveOrUpdateAccountTransactions() two DocumentsWriter try to write to same directory

This commit is contained in:
dankito 2020-04-28 17:13:17 +02:00
parent fb456c451a
commit b8bf67e2b8
1 changed files with 36 additions and 8 deletions

View File

@ -8,7 +8,6 @@ import net.dankito.banking.LuceneConfig.Companion.BookingDateFieldName
import net.dankito.banking.LuceneConfig.Companion.BookingDateSortFieldName import net.dankito.banking.LuceneConfig.Companion.BookingDateSortFieldName
import net.dankito.banking.LuceneConfig.Companion.BookingTextFieldName import net.dankito.banking.LuceneConfig.Companion.BookingTextFieldName
import net.dankito.banking.LuceneConfig.Companion.CurrencyFieldName 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.OtherPartyAccountIdFieldName
import net.dankito.banking.LuceneConfig.Companion.OtherPartyBankCodeFieldName import net.dankito.banking.LuceneConfig.Companion.OtherPartyBankCodeFieldName
import net.dankito.banking.LuceneConfig.Companion.OtherPartyNameFieldName import net.dankito.banking.LuceneConfig.Companion.OtherPartyNameFieldName
@ -21,6 +20,7 @@ import net.dankito.utils.serialization.ISerializer
import net.dankito.utils.serialization.JacksonJsonSerializer import net.dankito.utils.serialization.JacksonJsonSerializer
import org.apache.lucene.index.IndexableField import org.apache.lucene.index.IndexableField
import java.io.File import java.io.File
import java.util.concurrent.atomic.AtomicInteger
open class LuceneBankingPersistence( open class LuceneBankingPersistence(
@ -32,17 +32,24 @@ open class LuceneBankingPersistence(
protected val fields = FieldBuilder() protected val fields = FieldBuilder()
protected var documentsWriter: DocumentsWriter? = null
protected val countWriterUsages = AtomicInteger(0)
override fun saveOrUpdateAccountTransactions(bankAccount: BankAccount, transactions: List<AccountTransaction>) { override fun saveOrUpdateAccountTransactions(bankAccount: BankAccount, transactions: List<AccountTransaction>) {
DocumentsWriter(LuceneConfig.getAccountTransactionsIndexFolder(indexFolder)).use { writer -> val writer = getWriter()
transactions.forEach { transaction ->
writer.updateDocumentForNonNullFields(IdFieldName, transaction.id,
*createFieldsForAccountTransaction(bankAccount, transaction).toTypedArray()
)
}
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<IndexableField?> { protected open fun createFieldsForAccountTransaction(bankAccount: BankAccount, transaction: AccountTransaction): List<IndexableField?> {
@ -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()
}
}
} }