JetBrains / JetBrains/Exposed

Race Condition With Explicit Database for Transactions

Open
#1,267 2 comments 0 reactions 0 assignees View on GitHub
Dominant language
Kotlin
Stars
9.3k
Forks
798
Avg merge
4d 2h
Merged PRs (30d)
26

Description

# STEPS TO REPRODUCE
1. Create an in-memory database
```
val database: Database = when (type) {
is Type.Memory -> {
// https://github.com/JetBrains/Exposed/issues/726
val cfg: HikariConfig = HikariConfig().apply {
jdbcUrl = "jdbc:sqlite::memory:?foreign_keys=on"
}
val dataSource = HikariDataSource(cfg)
Database.connect(dataSource)
}
}.apply {
transactionManager.defaultIsolationLevel = java.sql.Connection.TRANSACTION_SERIALIZABLE
}.also {
transaction {
SchemaUtils.createMissingTablesAndColumns(
SubjectTableDefinition
}
}
```
2. Create a transaction with an **explicit** reference to the database
```
val fixtureSubject = SubjectFixture.newIdentifiedSubject()

transaction(database) {
SubjectTableDefinition.insertBlocking(fixtureSubject)
}
```
where
```
object SubjectTableDefinition : UUIDTable("subject") {
val sex = enumeration("sex", Sex::class)
val yearOfBirth = integer("year_of_birth")

fun insertBlocking(identifiedSubject: Identified) = insert {
it[id] = EntityID(identifiedSubject.id, SubjectTableDefinition)
it[sex] = identifiedSubject.value.sex
it[yearOfBirth] = identifiedSubject.value.yearOfBirth
}
```

# RESULTS
## Actual
With a high probability, an exception is thrown that the "subject" table does not exist.

## Expected
No exception is thrown, because the table clearly exists.

# NOTES
This is not 100% reproducible, as it might be a race condition. There seems to be a difference between implicit and explicit database references for transaction, where implicit references seem not to hit the issue. E.g. `transaction {}` versus `transaction(database) {}`.

It also seems less likely to occur if I use a file-based database, which might indicate that Hikari plays a role in this although this is not yet clear. (I'm only using Hikari as a workaround for #726.)

I'm only encountering this in my tests, not at runtime with my application. This might also be because my tests are setting up and tearing down databases several hundred times across a number of different tests, which could increase the probability of hitting race conditions.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.