transaction_isolation 1.0.2 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +1 -1
- data/README.md +18 -9
- data/lib/transaction_isolation/version.rb +1 -1
- data/test/integration/active_record/connection_adapters/any_adapter/translate_exception_test.rb +1 -7
- data/test/library_setup.rb +3 -0
- data/{transaction-isolation.gemspec → transaction_isolation.gemspec} +3 -1
- metadata +12 -10
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
# transaction_isolation
|
2
2
|
|
3
|
-
|
3
|
+
Set transaction isolation level in the ActiveRecord in a database agnostic way.
|
4
|
+
Works with MySQL, PostgreSQL and SQLite as long as you are using new adapters mysql2, pg or sqlite3.
|
5
|
+
Supports all ANSI SQL isolation levels: :serializable, :repeatable_read, :read_committed, :read_uncommitted.
|
4
6
|
|
5
7
|
## Example
|
6
8
|
|
@@ -18,7 +20,7 @@ Then run:
|
|
18
20
|
|
19
21
|
bundle
|
20
22
|
|
21
|
-
|
23
|
+
__It works out of the box with Ruby on Rails__.
|
22
24
|
|
23
25
|
If you have a standalone ActiveRecord-based project you'll need to call:
|
24
26
|
|
@@ -28,21 +30,23 @@ __after__ connecting to the database. This is because ActiveRecord loads adapter
|
|
28
30
|
|
29
31
|
## Features
|
30
32
|
|
31
|
-
* Setting transaction isolation level
|
33
|
+
* Setting transaction isolation level: :serializable, :repeatable_read, :read_committed, :read_uncommitted
|
32
34
|
* Auto-reverting to the original isolation level after the block
|
33
35
|
* Database agnostic
|
34
|
-
*
|
36
|
+
* MySQL, PostgreSQL and SQLite supported
|
35
37
|
* Exception translation. All deadlocks and serialization errors are wrapped in a ActiveRecord::TransactionIsolationConflict exception
|
36
38
|
* Use it in your Rails application or a standalone ActiveRecord-based project
|
37
39
|
|
40
|
+
## Testimonials
|
41
|
+
|
42
|
+
This gem was initially developed for and successfully works in production at [Kontomierz.pl](http://kontomierz.pl) - the finest Polish personal finance app.
|
43
|
+
|
38
44
|
## Real world example
|
39
45
|
|
40
46
|
When implementing a table-based job queue you should ensure that only one worker process can pop a particular job from the queue.
|
41
47
|
Wrapping your code in a transaction is not enough because by default databases do not isolate transactions to the full extent,
|
42
48
|
which leads to occasional phantom reads. It is therefore necessary to manually raise the transaction isolation level.
|
43
|
-
The highest level of transaction isolation is called "serializable"
|
44
|
-
|
45
|
-
[Read about isolation levels in Wikipedia](http://tinyurl.com/nrqjbb)
|
49
|
+
The highest level of transaction isolation is called "serializable" and that's what we need here:
|
46
50
|
|
47
51
|
class QueuedJob < ActiveRecord::Base
|
48
52
|
|
@@ -64,14 +68,19 @@ The highest level of transaction isolation is called "serializable".
|
|
64
68
|
end
|
65
69
|
end
|
66
70
|
end
|
71
|
+
rescue ActiveRecord::TransactionConflictError => e
|
72
|
+
logger.warn( e.message )
|
73
|
+
retry
|
67
74
|
end
|
68
75
|
|
69
76
|
end
|
70
77
|
|
78
|
+
[Read more about isolation levels in Wikipedia](http://tinyurl.com/nrqjbb)
|
79
|
+
|
71
80
|
## Requirements
|
72
81
|
|
73
|
-
* Ruby 1.9
|
74
|
-
* ActiveRecord 3.
|
82
|
+
* Ruby 1.9.2
|
83
|
+
* ActiveRecord 3.0.11+
|
75
84
|
|
76
85
|
## Running tests
|
77
86
|
|
data/test/integration/active_record/connection_adapters/any_adapter/translate_exception_test.rb
CHANGED
@@ -34,13 +34,7 @@ class ActiveRecordTest < MiniTest::Unit::TestCase
|
|
34
34
|
translated_exception = ActiveRecord::Base.connection.send( :translate_exception, StandardError.new( message ), message )
|
35
35
|
assert_equal( ActiveRecord::TransactionIsolationConflict, translated_exception.class )
|
36
36
|
end
|
37
|
-
|
38
|
-
# assert_equal( :read_committed, ActiveRecord::Base.connection.current_isolation_level )
|
39
|
-
#end
|
40
|
-
#
|
41
|
-
#if defined?( ActiveRecord::ConnectionAdapters::SQLite3Adapter )
|
42
|
-
# assert_equal( :serializable, ActiveRecord::Base.connection.current_isolation_level )
|
43
|
-
#end
|
37
|
+
|
44
38
|
end
|
45
39
|
|
46
40
|
end
|
data/test/library_setup.rb
CHANGED
@@ -19,4 +19,7 @@ TransactionIsolation::Test::Migrations.run!
|
|
19
19
|
# Load the code that will be tested
|
20
20
|
require 'transaction_isolation'
|
21
21
|
|
22
|
+
require 'logger'
|
23
|
+
ActiveRecord::Base.logger = Logger.new( File.expand_path( "#{File.dirname( __FILE__ )}/log/test.log" ) )
|
24
|
+
|
22
25
|
TransactionIsolation.apply_activerecord_patch
|
@@ -9,7 +9,9 @@ Gem::Specification.new do |s|
|
|
9
9
|
s.email = ["qertoip@gmail.com"]
|
10
10
|
s.homepage = "https://github.com/qertoip/transaction_isolation"
|
11
11
|
s.summary = %q{Set transaction isolation level in the ActiveRecord in a database agnostic way.}
|
12
|
-
s.description = %q{Set transaction isolation level in the ActiveRecord in a database agnostic way.
|
12
|
+
s.description = %q{Set transaction isolation level in the ActiveRecord in a database agnostic way.
|
13
|
+
Works with MySQL, PostgreSQL and SQLite as long as you are using new adapters mysql2, pg or sqlite3.
|
14
|
+
Supports all ANSI SQL isolation levels: :serializable, :repeatable_read, :read_committed, :read_uncommitted.}
|
13
15
|
s.required_ruby_version = '>= 1.9.2'
|
14
16
|
|
15
17
|
s.files = `git ls-files`.split("\n")
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: transaction_isolation
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.3
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-02-
|
12
|
+
date: 2012-02-08 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activerecord
|
16
|
-
requirement: &
|
16
|
+
requirement: &16306400 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,15 @@ dependencies:
|
|
21
21
|
version: 3.0.11
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *16306400
|
25
25
|
description: ! 'Set transaction isolation level in the ActiveRecord in a database
|
26
|
-
agnostic way.
|
27
|
-
|
26
|
+
agnostic way.
|
27
|
+
|
28
|
+
Works with MySQL, PostgreSQL and SQLite as long as you are using new adapters mysql2,
|
29
|
+
pg or sqlite3.
|
30
|
+
|
31
|
+
Supports all ANSI SQL isolation levels: :serializable, :repeatable_read, :read_committed,
|
32
|
+
:read_uncommitted.'
|
28
33
|
email:
|
29
34
|
- qertoip@gmail.com
|
30
35
|
executables: []
|
@@ -61,7 +66,7 @@ files:
|
|
61
66
|
- test/test_helper.rb
|
62
67
|
- test/test_runner.rb
|
63
68
|
- tests
|
64
|
-
-
|
69
|
+
- transaction_isolation.gemspec
|
65
70
|
homepage: https://github.com/qertoip/transaction_isolation
|
66
71
|
licenses: []
|
67
72
|
post_install_message:
|
@@ -80,9 +85,6 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
80
85
|
- - ! '>='
|
81
86
|
- !ruby/object:Gem::Version
|
82
87
|
version: '0'
|
83
|
-
segments:
|
84
|
-
- 0
|
85
|
-
hash: 3266208517833567002
|
86
88
|
requirements: []
|
87
89
|
rubyforge_project:
|
88
90
|
rubygems_version: 1.8.15
|