提交 c627590f 编写于 作者: J Jeremy Kemper

Rollback if commit raises an exception. Closes #8642.

git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@7088 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
上级 40f6e9f8
*SVN*
* Rollback if commit raises an exception. #8642 [kik, Jeremy Kemper]
* Update tests' use of fixtures for the new collections api. #8726 [kamal]
* Save associated records only if the association is already loaded. #8713 [blaine]
......
......@@ -57,7 +57,7 @@ def transaction(start_db_transaction = true)
transaction_open = true
end
yield
end
end
rescue Exception => database_transaction_rollback
if transaction_open
transaction_open = false
......@@ -66,7 +66,14 @@ def transaction(start_db_transaction = true)
raise unless database_transaction_rollback.is_a? ActiveRecord::Rollback
end
ensure
commit_db_transaction if transaction_open
if transaction_open
begin
commit_db_transaction
rescue Exception => database_transaction_rollback
rollback_db_transaction
raise
end
end
end
# Begins the transaction (and turns off auto-committing).
......
......@@ -81,12 +81,12 @@ def test_failing_on_exception
assert @first.approved?, "First should still be changed in the objects"
assert !@second.approved?, "Second should still be changed in the objects"
assert !Topic.find(1).approved?, "First shouldn't have been approved"
assert Topic.find(2).approved?, "Second should still be approved"
end
def test_callback_rollback_in_save
add_exception_raising_after_save_callback_to_topic
......@@ -101,7 +101,7 @@ def test_callback_rollback_in_save
remove_exception_raising_after_save_callback_to_topic
end
end
def test_callback_rollback_in_create
new_topic = Topic.new(
:title => "A new topic",
......@@ -149,36 +149,48 @@ def test_nested_explicit_transactions
end
def test_manually_rolling_back_a_transaction
Topic.transaction do
Topic.transaction do
@first.approved = true
@second.approved = false
@first.save
@second.save
raise ActiveRecord::Rollback
end
assert @first.approved?, "First should still be changed in the objects"
assert !@second.approved?, "Second should still be changed in the objects"
assert !Topic.find(1).approved?, "First shouldn't have been approved"
assert Topic.find(2).approved?, "Second should still be approved"
end
uses_mocha 'mocking connection.commit_db_transaction' do
def test_rollback_when_commit_raises
Topic.connection.expects(:commit_db_transaction).raises('OH NOES')
Topic.connection.expects(:rollback_db_transaction)
assert_raise RuntimeError do
Topic.transaction do
# do nothing
end
end
end
end
private
def add_exception_raising_after_save_callback_to_topic
Topic.class_eval { def after_save() raise "Make the transaction rollback" end }
end
def remove_exception_raising_after_save_callback_to_topic
Topic.class_eval { remove_method :after_save }
end
def add_exception_raising_after_create_callback_to_topic
Topic.class_eval { def after_create() raise "Make the transaction rollback" end }
end
def remove_exception_raising_after_create_callback_to_topic
Topic.class_eval { remove_method :after_create }
end
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册