Module: ActiveRecord::ConnectionAdapters::CockroachDB::TransactionManagerMonkeyPatch
- Included in:
- TransactionManager
- Defined in:
- lib/active_record/connection_adapters/cockroachdb/transaction_manager.rb
Instance Method Summary collapse
- #retryable?(error) ⇒ Boolean
- #serialization_error?(error) ⇒ Boolean
- #sleep_rand_seconds(attempts) ⇒ Object
-
#within_new_transaction(isolation: nil, joinable: true, attempts: 0) ⇒ Object
Capture ActiveRecord::SerializationFailure errors caused by transactions that fail due to serialization errors.
Instance Method Details
#retryable?(error) ⇒ Boolean
34 35 36 37 38 39 |
# File 'lib/active_record/connection_adapters/cockroachdb/transaction_manager.rb', line 34 def retryable?(error) return true if serialization_error?(error) return true if error.is_a? ActiveRecord::SerializationFailure return retryable? error.cause if error.cause false end |
#serialization_error?(error) ⇒ Boolean
41 42 43 44 45 |
# File 'lib/active_record/connection_adapters/cockroachdb/transaction_manager.rb', line 41 def serialization_error?(error) errors = [error] errors << error.cause if error.cause errors.any? {|e| e.is_a? PG::TRSerializationFailure } end |
#sleep_rand_seconds(attempts) ⇒ Object
47 48 49 50 |
# File 'lib/active_record/connection_adapters/cockroachdb/transaction_manager.rb', line 47 def sleep_rand_seconds(attempts) sleep_seconds = (2 ** attempts + rand) / 10 sleep(sleep_seconds) end |
#within_new_transaction(isolation: nil, joinable: true, attempts: 0) ⇒ Object
Capture ActiveRecord::SerializationFailure errors caused by transactions that fail due to serialization errors. Failed transactions will be retried until they pass or the max retry limit is exceeded.
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
# File 'lib/active_record/connection_adapters/cockroachdb/transaction_manager.rb', line 11 def within_new_transaction(isolation: nil, joinable: true, attempts: 0) super(isolation: isolation, joinable: joinable) rescue ActiveRecord::ConnectionNotEstablished => error raise unless retryable? error raise if attempts >= @connection.max_transaction_retries sleep_rand_seconds(attempts) unless @connection.active? warn "connection isn't active, reconnecting" @connection.reconnect! end within_new_transaction(isolation: isolation, joinable: joinable, attempts: attempts + 1) { yield } rescue ActiveRecord::StatementInvalid => error raise unless retryable? error raise if attempts >= @connection.max_transaction_retries sleep_rand_seconds(attempts) within_new_transaction(isolation: isolation, joinable: joinable, attempts: attempts + 1) { yield } end |