odavid / typeorm-transactional-cls-hooked

A Transactional Method Decorator for typeorm that uses cls-hooked to handle and propagate transactions between different repositories and service methods. Inpired by Spring Trasnactional Annotation and Sequelize CLS
MIT License
522 stars 86 forks source link

Transactions not working with multiple DBs (connections) #90

Closed Dzeri96 closed 3 years ago

Dzeri96 commented 3 years ago

I am using the typeorm-test-transactions package to run transactional tests. As the package is essentially just a wrapper for this one, I assume I should post here. If not please correct me.

We have 2 connections to a postgres and a timescale DB in our app and those are initialized in one 'root' test as follows:

var connections = await createConnections([
        {
            type: 'postgres',
            name: 'default',
            host: process.env.TESTDB_HOST,
            port: +process.env.TESTDB_PORT,
            username: process.env.TESTDB_USER,
            password: process.env.TESTDB_PASS,
            database: process.env.TESTDB_DB,
            entities: ['./src/shared/models/default/**/*.entity.ts'],
            migrations: ['./src/shared/migrations/default/*.ts'],
            logging: ['error', 'warn'],
            synchronize: false,
            cli: {
                migrationsDir: './src/shared/migrations/default'
            }
        },
        {
            type: 'postgres',
            name: 'timescale',
            host: process.env.TESTDB_TIMESCALE_HOST,
            port: +process.env.TESTDB_TIMESCALE_PORT,
            username: process.env.TESTDB_TIMESCALE_USER,
            password: process.env.TESTDB_TIMESCALE_PASS,
            database: process.env.TESTDB_TIMESCALE_DB,
            entities: ['./src/shared/models/timescale/**/*.entity.ts'],
            migrations: ['./src/shared/migrations/timescale/*.ts'],
            logging: ['error', 'warn'],
            synchronize: false,
            cli: {
                migrationsDir: './src/shared/migrations/timescale'
            }
        }
    ]);

In one of our tests, we access a repository like so: repository = getConnection('timescale').getCustomRepository(CandleRepository);

The problem is that, when getting a non-default connection, the transactions don't seem to work. If I delete the default connection, rename the timescale one and re-run the tests, everything works as expected, i.e. the tests don't affect each other.

Could this be an issue with your project and how could we solve it? I'd be prepared to do a PR if it's not too complicated to get into the project's code.

odavid commented 3 years ago

Transactional decorator has ability to define which connection should be open the transaction. It has also the ability to define a function that will return the connection name.

See https://github.com/odavid/typeorm-transactional-cls-hooked/issues/43 and https://github.com/odavid/typeorm-transactional-cls-hooked/issues/44

I know it worked for @Melzar back then...

Dzeri96 commented 3 years ago

Thanks for the rapid response, I will probably have to drop typeorm-test-transactions and use this package directly. In that case, could I use two annotations on one test that requires transactions to both databases?

odavid commented 3 years ago

Did not test it myself, but don't see any reason why not.

Dzeri96 commented 3 years ago

I forked the wrapper library and I managed to make the second connection work using the function as a parameter for the decorator. In some tests we need transactions to both databases so I'm wondering if maybe we could extend this project with that functionality (to recieve an array of connectionNames), or if I should make a PR for the wrapper which calls a transactional function recursively with different connections?

odavid commented 3 years ago

I prefer to keep this project as thin as it can. Will be happy if it will be implemented within the wrapper lib. Thank you!

odavid commented 3 years ago

@Dzeri96 - I am closing this issue.