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
48 49 50 51 52 53 |
# File 'lib/active_record/connection_adapters/cockroachdb/transaction_manager.rb', line 48 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
55 56 57 58 59 |
# File 'lib/active_record/connection_adapters/cockroachdb/transaction_manager.rb', line 55 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
61 62 63 64 |
# File 'lib/active_record/connection_adapters/cockroachdb/transaction_manager.rb', line 61 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.
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
# File 'lib/active_record/connection_adapters/cockroachdb/transaction_manager.rb', line 25 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 |