Class: ActiveRecord::ConnectionAdapters::TransactionManager
- Inherits:
-
Object
- Object
- ActiveRecord::ConnectionAdapters::TransactionManager
- Defined in:
- lib/active_record/connection_adapters/abstract/transaction.rb
Overview
:nodoc:
Instance Method Summary collapse
- #begin_transaction(isolation: nil, joinable: true, _lazy: true) ⇒ Object
- #commit_transaction ⇒ Object
- #current_transaction ⇒ Object
- #dirty_current_transaction ⇒ Object
- #disable_lazy_transactions! ⇒ Object
- #enable_lazy_transactions! ⇒ Object
-
#initialize(connection) ⇒ TransactionManager
constructor
A new instance of TransactionManager.
- #lazy_transactions_enabled? ⇒ Boolean
- #materialize_transactions ⇒ Object
- #open_transactions ⇒ Object
- #restorable? ⇒ Boolean
- #restore_transactions ⇒ Object
- #rollback_transaction(transaction = nil) ⇒ Object
- #within_new_transaction(isolation: nil, joinable: true) ⇒ Object
Constructor Details
#initialize(connection) ⇒ TransactionManager
Returns a new instance of TransactionManager.
400 401 402 403 404 405 406 |
# File 'lib/active_record/connection_adapters/abstract/transaction.rb', line 400 def initialize(connection) @stack = [] @connection = connection @has_unmaterialized_transactions = false @materializing_transactions = false @lazy_transactions_enabled = true end |
Instance Method Details
#begin_transaction(isolation: nil, joinable: true, _lazy: true) ⇒ Object
408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 |
# File 'lib/active_record/connection_adapters/abstract/transaction.rb', line 408 def begin_transaction(isolation: nil, joinable: true, _lazy: true) @connection.lock.synchronize do run_commit_callbacks = !current_transaction.joinable? transaction = if @stack.empty? RealTransaction.new( @connection, isolation: isolation, joinable: joinable, run_commit_callbacks: run_commit_callbacks ) elsif current_transaction.restartable? RestartParentTransaction.new( @connection, current_transaction, isolation: isolation, joinable: joinable, run_commit_callbacks: run_commit_callbacks ) else SavepointTransaction.new( @connection, "active_record_#{@stack.size}", current_transaction, isolation: isolation, joinable: joinable, run_commit_callbacks: run_commit_callbacks ) end unless transaction.materialized? if @connection.supports_lazy_transactions? && lazy_transactions_enabled? && _lazy @has_unmaterialized_transactions = true else transaction.materialize! end end @stack.push(transaction) transaction end end |
#commit_transaction ⇒ Object
495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 |
# File 'lib/active_record/connection_adapters/abstract/transaction.rb', line 495 def commit_transaction @connection.lock.synchronize do transaction = @stack.last begin transaction.before_commit_records ensure @stack.pop end dirty_current_transaction if transaction.dirty? transaction.commit transaction.commit_records end end |
#current_transaction ⇒ Object
581 582 583 |
# File 'lib/active_record/connection_adapters/abstract/transaction.rb', line 581 def current_transaction @stack.last || NULL_TRANSACTION end |
#dirty_current_transaction ⇒ Object
463 464 465 |
# File 'lib/active_record/connection_adapters/abstract/transaction.rb', line 463 def dirty_current_transaction current_transaction.dirty! end |
#disable_lazy_transactions! ⇒ Object
450 451 452 453 |
# File 'lib/active_record/connection_adapters/abstract/transaction.rb', line 450 def disable_lazy_transactions! materialize_transactions @lazy_transactions_enabled = false end |
#enable_lazy_transactions! ⇒ Object
455 456 457 |
# File 'lib/active_record/connection_adapters/abstract/transaction.rb', line 455 def enable_lazy_transactions! @lazy_transactions_enabled = true end |
#lazy_transactions_enabled? ⇒ Boolean
459 460 461 |
# File 'lib/active_record/connection_adapters/abstract/transaction.rb', line 459 def lazy_transactions_enabled? @lazy_transactions_enabled end |
#materialize_transactions ⇒ Object
479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 |
# File 'lib/active_record/connection_adapters/abstract/transaction.rb', line 479 def materialize_transactions return if @materializing_transactions if @has_unmaterialized_transactions @connection.lock.synchronize do begin @materializing_transactions = true @stack.each { |t| t.materialize! unless t.materialized? } ensure @materializing_transactions = false end @has_unmaterialized_transactions = false end end end |
#open_transactions ⇒ Object
577 578 579 |
# File 'lib/active_record/connection_adapters/abstract/transaction.rb', line 577 def open_transactions @stack.size end |
#restorable? ⇒ Boolean
475 476 477 |
# File 'lib/active_record/connection_adapters/abstract/transaction.rb', line 475 def restorable? @stack.none?(&:dirty?) end |
#restore_transactions ⇒ Object
467 468 469 470 471 472 473 |
# File 'lib/active_record/connection_adapters/abstract/transaction.rb', line 467 def restore_transactions return false unless restorable? @stack.each(&:restore!) true end |
#rollback_transaction(transaction = nil) ⇒ Object
512 513 514 515 516 517 518 519 520 521 522 |
# File 'lib/active_record/connection_adapters/abstract/transaction.rb', line 512 def rollback_transaction(transaction = nil) @connection.lock.synchronize do transaction ||= @stack.last begin transaction.rollback ensure @stack.pop if @stack.last == transaction end transaction.rollback_records end end |
#within_new_transaction(isolation: nil, joinable: true) ⇒ Object
524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 |
# File 'lib/active_record/connection_adapters/abstract/transaction.rb', line 524 def within_new_transaction(isolation: nil, joinable: true) @connection.lock.synchronize do transaction = begin_transaction(isolation: isolation, joinable: joinable) begin ret = yield completed = true ret rescue Exception => error rollback_transaction after_failure_actions(transaction, error) raise ensure unless error # In 7.1 we enforce timeout >= 0.4.0 which no longer use throw, so we can # go back to the original behavior of committing on non-local return. # If users are using throw, we assume it's not an error case. completed = true if ActiveRecord.commit_transaction_on_non_local_return if Thread.current.status == "aborting" rollback_transaction elsif !completed && transaction.written ActiveRecord.deprecator.warn(<<~EOW) A transaction is being rolled back because the transaction block was exited using `return`, `break` or `throw`. In Rails 7.2 this transaction will be committed instead. To opt-in to the new behavior now and suppress this warning you can set: Rails.application.config.active_record.commit_transaction_on_non_local_return = true EOW rollback_transaction else begin commit_transaction rescue ActiveRecord::ConnectionFailed transaction.invalidate! unless transaction.state.completed? raise rescue Exception rollback_transaction(transaction) unless transaction.state.completed? raise end end end end ensure unless transaction&.state&.completed? @connection.throw_away! transaction&.incomplete! end end end |