Whereas ActiveRecord works fairly nice throughout most eventualities, it struggles with multi-database architectures.
Fortuitously, the previous few releases have had a number of work completed on this side.
One main disadvantage is the way in which transactions work in a multi-database structure.
A transaction is principally a set of database operations which can be carried out as a single unit.
Right here’s an instance,
Although there are two database operations (Firm.first.contact and Firm.final.contact),
they’re carried out inside a single transaction.
Nonetheless, while you use a transaction throughout a number of databases,
it’s primarily left up-to the developer to make sure that the transactions are distributed throughout the databases in a approach that’s in keeping with the meant use case.
It’s because transactions work on a single database connection.
Earlier than
Let’s take the instance of a multi-database structure the place there’s a Firm mannequin on the first database
and a Freelancer mannequin on the secondary database.
Each these fashions are linked through the has_many :via affiliation
through the Contract mannequin on the first database.
As you’ll be able to see, two transactions happen to insert two data into the contract desk.
It’s because the firm.freelancers = [freelancer1, freelancer2] operation is carried out on the first database connection
and the Contract.create! operation is carried out on the secondary database connection.
It’s as much as the developer to wrap this round a double transaction block to make sure that the 2 operations are carried out
inside a single transaction.
After
Due to this PR that updates
how through_reflection distributes transactions throughout database connections,
we are able to now carry out the identical operation with out the necessity for a double transaction block.
This was achieved through a quite simple replace to the ThroughAssociation module.
The transaction methodology opens up the second block with the connection of the through_reflection
as a substitute of the source_reflection.