Class: ActiveRecord::ConnectionAdapters::TransactionManager
- Defined in:
- activerecord/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.
355 356 357 358 359 360 361 |
# File 'activerecord/lib/active_record/connection_adapters/abstract/transaction.rb', line 355 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
363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 |
# File 'activerecord/lib/active_record/connection_adapters/abstract/transaction.rb', line 363 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
450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 |
# File 'activerecord/lib/active_record/connection_adapters/abstract/transaction.rb', line 450 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? if current_transaction.open? current_transaction.written_indirectly ||= transaction.written || transaction.written_indirectly end transaction.commit transaction.commit_records end end |
#current_transaction ⇒ Object
546 547 548 |
# File 'activerecord/lib/active_record/connection_adapters/abstract/transaction.rb', line 546 def current_transaction @stack.last || NULL_TRANSACTION end |
#dirty_current_transaction ⇒ Object
418 419 420 |
# File 'activerecord/lib/active_record/connection_adapters/abstract/transaction.rb', line 418 def dirty_current_transaction current_transaction.dirty! end |
#disable_lazy_transactions! ⇒ Object
405 406 407 408 |
# File 'activerecord/lib/active_record/connection_adapters/abstract/transaction.rb', line 405 def disable_lazy_transactions! materialize_transactions @lazy_transactions_enabled = false end |
#enable_lazy_transactions! ⇒ Object
410 411 412 |
# File 'activerecord/lib/active_record/connection_adapters/abstract/transaction.rb', line 410 def enable_lazy_transactions! @lazy_transactions_enabled = true end |
#lazy_transactions_enabled? ⇒ Boolean
414 415 416 |
# File 'activerecord/lib/active_record/connection_adapters/abstract/transaction.rb', line 414 def lazy_transactions_enabled? @lazy_transactions_enabled end |
#materialize_transactions ⇒ Object
434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 |
# File 'activerecord/lib/active_record/connection_adapters/abstract/transaction.rb', line 434 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
542 543 544 |
# File 'activerecord/lib/active_record/connection_adapters/abstract/transaction.rb', line 542 def open_transactions @stack.size end |
#restorable? ⇒ Boolean
430 431 432 |
# File 'activerecord/lib/active_record/connection_adapters/abstract/transaction.rb', line 430 def restorable? @stack.none?(&:dirty?) end |
#restore_transactions ⇒ Object
422 423 424 425 426 427 428 |
# File 'activerecord/lib/active_record/connection_adapters/abstract/transaction.rb', line 422 def restore_transactions return false unless restorable? @stack.each(&:restore!) true end |
#rollback_transaction(transaction = nil) ⇒ Object
471 472 473 474 475 476 477 478 479 480 481 |
# File 'activerecord/lib/active_record/connection_adapters/abstract/transaction.rb', line 471 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
483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 |
# File 'activerecord/lib/active_record/connection_adapters/abstract/transaction.rb', line 483 def within_new_transaction(isolation: nil, joinable: true) @connection.lock.synchronize do transaction = begin_transaction(isolation: isolation, joinable: joinable) ret = yield completed = true ret rescue Exception => error if transaction rollback_transaction after_failure_actions(transaction, error) end raise ensure if transaction if error # @connection still holds an open or invalid transaction, so we must not # put it back in the pool for reuse. @connection.throw_away! unless transaction.state.rolledback? else if Thread.current.status == "aborting" rollback_transaction elsif !completed && transaction.written # This was deprecated in 6.1, and has now changed to a rollback rollback_transaction elsif !completed && !transaction.written_indirectly # This was a silent commit in 6.1, but now becomes a rollback; we skipped # the warning because (having not been written) the change generally won't # have any effect rollback_transaction else if !completed && transaction.written_indirectly # This is the case that was missed in the 6.1 deprecation, so we have to # do it now ActiveRecord.deprecator.warn(<<~EOW) Using `return`, `break` or `throw` to exit a transaction block is deprecated without replacement. If the `throw` came from `Timeout.timeout(duration)`, pass an exception class as a second argument so it doesn't use `throw` to abort its block. This results in the transaction being committed, but in the next release of Rails it will rollback. EOW end 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 end end |