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.
407 408 409 410 411 412 413 |
# File 'lib/active_record/connection_adapters/abstract/transaction.rb', line 407 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
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 449 450 451 452 453 454 455 |
# File 'lib/active_record/connection_adapters/abstract/transaction.rb', line 415 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
502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 |
# File 'lib/active_record/connection_adapters/abstract/transaction.rb', line 502 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
588 589 590 |
# File 'lib/active_record/connection_adapters/abstract/transaction.rb', line 588 def current_transaction @stack.last || NULL_TRANSACTION end |
#dirty_current_transaction ⇒ Object
470 471 472 |
# File 'lib/active_record/connection_adapters/abstract/transaction.rb', line 470 def dirty_current_transaction current_transaction.dirty! end |
#disable_lazy_transactions! ⇒ Object
457 458 459 460 |
# File 'lib/active_record/connection_adapters/abstract/transaction.rb', line 457 def disable_lazy_transactions! materialize_transactions @lazy_transactions_enabled = false end |
#enable_lazy_transactions! ⇒ Object
462 463 464 |
# File 'lib/active_record/connection_adapters/abstract/transaction.rb', line 462 def enable_lazy_transactions! @lazy_transactions_enabled = true end |
#lazy_transactions_enabled? ⇒ Boolean
466 467 468 |
# File 'lib/active_record/connection_adapters/abstract/transaction.rb', line 466 def lazy_transactions_enabled? @lazy_transactions_enabled end |
#materialize_transactions ⇒ Object
486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 |
# File 'lib/active_record/connection_adapters/abstract/transaction.rb', line 486 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
584 585 586 |
# File 'lib/active_record/connection_adapters/abstract/transaction.rb', line 584 def open_transactions @stack.size end |
#restorable? ⇒ Boolean
482 483 484 |
# File 'lib/active_record/connection_adapters/abstract/transaction.rb', line 482 def restorable? @stack.none?(&:dirty?) end |
#restore_transactions ⇒ Object
474 475 476 477 478 479 480 |
# File 'lib/active_record/connection_adapters/abstract/transaction.rb', line 474 def restore_transactions return false unless restorable? @stack.each(&:restore!) true end |
#rollback_transaction(transaction = nil) ⇒ Object
519 520 521 522 523 524 525 526 527 528 529 |
# File 'lib/active_record/connection_adapters/abstract/transaction.rb', line 519 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
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 576 577 578 579 580 581 582 |
# File 'lib/active_record/connection_adapters/abstract/transaction.rb', line 531 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 |