mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Merge pull request #28726 from matthewd/transaction-locking
Add comprehensive locking around DB transactions
This commit is contained in:
commit
92ba89dbcc
3 changed files with 70 additions and 52 deletions
|
@ -149,6 +149,7 @@ module ActiveRecord
|
|||
end
|
||||
|
||||
def begin_transaction(options = {})
|
||||
@connection.lock.synchronize do
|
||||
run_commit_callbacks = !current_transaction.joinable?
|
||||
transaction =
|
||||
if @stack.empty?
|
||||
|
@ -161,8 +162,10 @@ module ActiveRecord
|
|||
@stack.push(transaction)
|
||||
transaction
|
||||
end
|
||||
end
|
||||
|
||||
def commit_transaction
|
||||
@connection.lock.synchronize do
|
||||
transaction = @stack.last
|
||||
|
||||
begin
|
||||
|
@ -174,14 +177,19 @@ module ActiveRecord
|
|||
transaction.commit
|
||||
transaction.commit_records
|
||||
end
|
||||
end
|
||||
|
||||
def rollback_transaction(transaction = nil)
|
||||
@connection.lock.synchronize do
|
||||
transaction ||= @stack.pop
|
||||
transaction.rollback
|
||||
transaction.rollback_records
|
||||
end
|
||||
end
|
||||
|
||||
def within_new_transaction(options = {})
|
||||
@connection.lock.synchronize do
|
||||
begin
|
||||
transaction = begin_transaction options
|
||||
yield
|
||||
rescue Exception => error
|
||||
|
@ -204,6 +212,8 @@ module ActiveRecord
|
|||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def open_transactions
|
||||
@stack.size
|
||||
|
|
|
@ -74,7 +74,7 @@ module ActiveRecord
|
|||
SIMPLE_INT = /\A\d+\z/
|
||||
|
||||
attr_accessor :visitor, :pool
|
||||
attr_reader :schema_cache, :owner, :logger, :prepared_statements
|
||||
attr_reader :schema_cache, :owner, :logger, :prepared_statements, :lock
|
||||
alias :in_use? :owner
|
||||
|
||||
def self.type_cast_config_to_integer(config)
|
||||
|
|
|
@ -239,7 +239,9 @@ module ActiveRecord
|
|||
|
||||
# Is this connection alive and ready for queries?
|
||||
def active?
|
||||
@lock.synchronize do
|
||||
@connection.query "SELECT 1"
|
||||
end
|
||||
true
|
||||
rescue PG::Error
|
||||
false
|
||||
|
@ -247,12 +249,15 @@ module ActiveRecord
|
|||
|
||||
# Close then reopen the connection.
|
||||
def reconnect!
|
||||
@lock.synchronize do
|
||||
super
|
||||
@connection.reset
|
||||
configure_connection
|
||||
end
|
||||
end
|
||||
|
||||
def reset!
|
||||
@lock.synchronize do
|
||||
clear_cache!
|
||||
reset_transaction
|
||||
unless @connection.transaction_status == ::PG::PQTRANS_IDLE
|
||||
|
@ -261,13 +266,16 @@ module ActiveRecord
|
|||
@connection.query "DISCARD ALL"
|
||||
configure_connection
|
||||
end
|
||||
end
|
||||
|
||||
# Disconnects from the database if already connected. Otherwise, this
|
||||
# method does nothing.
|
||||
def disconnect!
|
||||
@lock.synchronize do
|
||||
super
|
||||
@connection.close rescue nil
|
||||
end
|
||||
end
|
||||
|
||||
def native_database_types #:nodoc:
|
||||
NATIVE_DATABASE_TYPES
|
||||
|
|
Loading…
Reference in a new issue