Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge [5682] from trunk.

git-svn-id: http://svn-commit.rubyonrails.org/rails/branches/1-2-pre-release@5683 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
  • Loading branch information...
commit 762fc5447f37ca2af023cbcb449d377addffeaf0 1 parent bd261ff
@jeremy jeremy authored
View
2  activerecord/CHANGELOG
@@ -1,5 +1,7 @@
*1.15.0 RC2*
+* find supports :lock with :include. Check whether your database allows SELECT ... FOR UPDATE with outer joins before using. #6764 [vitaly, Jeremy Kemper]
+
* Subclasses of an abstract class work with single-table inheritance. #5704 [nick+rails@ag.arizona.edu, Ryan Davis, Jeremy Kemper]
* Support nil and Array in :conditions => { attr => value } hashes. #6548 [Assaf, Jeremy Kemper]
View
1  activerecord/lib/active_record/associations.rb
@@ -1172,6 +1172,7 @@ def construct_finder_sql_with_included_associations(options, join_dependency)
add_order!(sql, options[:order], scope)
add_limit!(sql, options, scope) if using_limitable_reflections?(join_dependency.reflections)
+ add_lock!(sql, options, scope)
return sanitize_sql(sql)
end
View
46 activerecord/test/locking_test.rb
@@ -63,12 +63,12 @@ def test_lock_column_is_mass_assignable
assert_equal 1, p1.lock_version
assert_equal p1.lock_version, Person.new(p1.attributes).lock_version
end
-
+
def test_lock_without_default_sets_version_to_zero
t1 = LockWithoutDefault.new
assert_equal 0, t1.lock_version
end
-
+
def test_lock_with_custom_column_without_default_sets_version_to_zero
t1 = LockWithCustomColumnWithoutDefault.new
assert_equal 0, t1.custom_lock_version
@@ -87,17 +87,17 @@ def test_lock_with_custom_column_without_default_sets_version_to_zero
class PessimisticLockingTest < Test::Unit::TestCase
self.use_transactional_fixtures = false
fixtures :people
-
+
def setup
@allow_concurrency = ActiveRecord::Base.allow_concurrency
ActiveRecord::Base.allow_concurrency = true
end
-
+
def teardown
ActiveRecord::Base.allow_concurrency = @allow_concurrency
end
-
- # Test that the adapter doesn't blow up on add_lock!
+
+ # Test typical find.
def test_sane_find_with_lock
assert_nothing_raised do
Person.transaction do
@@ -105,9 +105,9 @@ def test_sane_find_with_lock
end
end
end
-
- # Test no-blowup for scoped lock.
- def test_sane_find_with_lock
+
+ # Test scoped lock.
+ def test_sane_find_with_scoped_lock
assert_nothing_raised do
Person.transaction do
Person.with_scope(:find => { :lock => true }) do
@@ -116,7 +116,19 @@ def test_sane_find_with_lock
end
end
end
-
+
+ # PostgreSQL protests SELECT ... FOR UPDATE on an outer join.
+ unless current_adapter?(:PostgreSQLAdapter)
+ # Test locked eager find.
+ def test_eager_find_with_lock
+ assert_nothing_raised do
+ Person.transaction do
+ Reader.find 1, :include => :person, :lock => true
+ end
+ end
+ end
+ end
+
# Locking a record reloads it.
def test_sane_lock_method
assert_nothing_raised do
@@ -128,24 +140,24 @@ def test_sane_lock_method
end
end
end
-
+
if current_adapter?(:PostgreSQLAdapter, :OracleAdapter)
def test_no_locks_no_wait
first, second = duel { Person.find 1 }
assert first.end > second.end
end
-
+
def test_second_lock_waits
assert [0.2, 1, 5].any? { |zzz|
first, second = duel(zzz) { Person.find 1, :lock => true }
second.end > first.end
}
end
-
+
protected
def duel(zzz = 5)
t0, t1, t2, t3 = nil, nil, nil, nil
-
+
a = Thread.new do
t0 = Time.now
Person.transaction do
@@ -154,17 +166,17 @@ def duel(zzz = 5)
end
t1 = Time.now
end
-
+
b = Thread.new do
sleep zzz / 2.0 # ensure thread 1 tx starts first
t2 = Time.now
Person.transaction { yield }
t3 = Time.now
end
-
+
a.join
b.join
-
+
assert t1 > t0 + zzz
assert t2 > t0
assert t3 > t2
Please sign in to comment.
Something went wrong with that request. Please try again.