Between every test we run we create a new database...
# exposed
b
Between every test we run we create a new database by running
CREATE DATABASE ...;
and then connect to the new database by doing the regular
Database.connect(dataSource, databaseConfig = databaseConfig)
. The data source is a HikariDataSource and the database is Postgres. If we don't explicitly pass the database to the transaction then we sometimes experience a transaction using the database of a previous test. If we assign the returned database from the
Database.connect
function to a global variable and pass that to the transaction, it doesn't seem to happen. It seems there's something weird happening when assigning the default database. We've also tried setting the default database on TransactionManager and it did not make a difference. TL;DR: This sometimes produces race conditions if you recently connected to a new database:
Copy code
transaction { /* do Exposed stuff here */ }
This does not:
Copy code
transaction(database) { /* do Exposed stuff here */ }
d
Copy code
transaction { /* do Exposed stuff here */ }
↑ this will use the last Database.connect's connection
b
Yes. My problem is when I do Database.connect again later on to connect to a different database. Sometimes it will still use the previous database I connected to.
d
For as explicit as exposed is with things, I’m surprised that the transaction call doesn’t require a Database object, and instead tries to do magic. The solution is to always pass in the Database object yourself, never use
transaction
without it.
b
Yea, I've ended up doing it like this
Copy code
private lateinit var database: Database
fun <T> transaction(block: Transaction.() -> T): T = transaction(database) { block() }
d
I have very similar code in my projects too.
d
I always pass database object when using transaction
c
Hi @Bård Kristian If I'm understanding correctly, any previous database that a test connected to will not need to be kept for future use, since a new call to
Database.connect()
will be made? > We've also tried setting the default database on TransactionManager and it did not make a difference. If so, were you also scrapping the no-longer-needed implicit (or manually-set) default between tests? Something like, for example:
Copy code
TransactionManager.closeAndUnregister(TransactionManager.defaultDatabase)
b
Of course I am no longer able to reproduce it... A lot has changed in our tests and project since then. I will revert passing the database explicitly to the transaction and implement your suggestion and tell the team to let me know if they experience flaky tests.
thank you color 1