Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to set transaction isolation level using ActiveRecord connection?

I need to manage transaction isolation level on a per-transaction basis in a way portable across databases (SQLite, PostgreSQL, MySQL at least).

I know I can do it manually, like that:

User.connection.execute('SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE')

...but I would expect something like:

User.isolation_level( :serializable ) do
  # ...
end
like image 885
qertoip Avatar asked Feb 03 '12 10:02

qertoip


People also ask

How do I change the transaction isolation level?

To set the transaction isolation level, use an ISOLATION LEVEL level clause. It is not permitted to specify multiple ISOLATION LEVEL clauses in the same SET TRANSACTION statement. The default isolation level is REPEATABLE READ . Other permitted values are READ COMMITTED , READ UNCOMMITTED , and SERIALIZABLE .

How does ActiveRecord transaction work?

Transactions in ActiveRecordEvery database operation that happens inside that block will be sent to the database as a transaction. If any kind of unhandled error happens inside the block, the transaction will be aborted, and no changes will be made to the DB.

Which isolation level does support repeatable reads?

The default isolation level for InnoDB is REPEATABLE READ .

What is set transaction isolation level snapshot?

A transaction running under SNAPSHOT isolation level can view changes made by that transaction. For example, if the transaction performs an UPDATE on a table and then issues a SELECT statement against the same table, the modified data will be included in the result set.


2 Answers

This functionality is supported by ActiveRecord itself:

MyRecord.transaction(isolation: :read_committed) do
  # do your transaction work
end

It supports the ANSI SQL isolation levels:

  • :read_uncommitted
  • :read_committed
  • :repeatable_read
  • :serializable

This method is available since Rails 4, it was unavailable when the OP asked the question. But for any decently modern Rails application this should be the way to go.

like image 77
NobodysNightmare Avatar answered Sep 20 '22 14:09

NobodysNightmare


There was no gem available so I developed one (MIT): https://github.com/qertoip/transaction_isolation

like image 42
qertoip Avatar answered Sep 18 '22 14:09

qertoip