| 519 | } |
| 520 | |
| 521 | void Jrd::Attachment::resetSession(thread_db* tdbb, jrd_tra** traHandle) |
| 522 | { |
| 523 | jrd_tra* oldTran = traHandle ? *traHandle : nullptr; |
| 524 | if (att_transactions) |
| 525 | { |
| 526 | int n = 0; |
| 527 | bool err = false; |
| 528 | for (const jrd_tra* tra = att_transactions; tra; tra = tra->tra_next) |
| 529 | { |
| 530 | n++; |
| 531 | if (tra != oldTran && !(tra->tra_flags & TRA_prepared)) |
| 532 | err = true; |
| 533 | } |
| 534 | |
| 535 | // Cannot reset user session |
| 536 | // There are open transactions (@1 active) |
| 537 | if (err) |
| 538 | { |
| 539 | ERR_post(Arg::Gds(isc_ses_reset_err) << |
| 540 | Arg::Gds(isc_ses_reset_open_trans) << Arg::Num(n)); |
| 541 | } |
| 542 | } |
| 543 | |
| 544 | AutoSetRestoreFlag<ULONG> flags(&att_flags, ATT_resetting, true); |
| 545 | |
| 546 | ULONG oldFlags = 0; |
| 547 | SSHORT oldTimeout = 0; |
| 548 | RefPtr<JTransaction> jTran; |
| 549 | bool shutAtt = false; |
| 550 | try |
| 551 | { |
| 552 | // Run ON DISCONNECT trigger before reset |
| 553 | if (!(att_flags & ATT_no_db_triggers)) |
| 554 | runDBTriggers(tdbb, TRIGGER_DISCONNECT); |
| 555 | |
| 556 | // shutdown attachment on any error after this point |
| 557 | shutAtt = true; |
| 558 | |
| 559 | if (oldTran) |
| 560 | { |
| 561 | oldFlags = oldTran->tra_flags; |
| 562 | oldTimeout = oldTran->tra_lock_timeout; |
| 563 | jTran = oldTran->getInterface(false); |
| 564 | |
| 565 | // It will also run run ON TRANSACTION ROLLBACK triggers |
| 566 | JRD_rollback_transaction(tdbb, oldTran); |
| 567 | *traHandle = nullptr; |
| 568 | } |
| 569 | |
| 570 | // Session was reset with warning(s) |
| 571 | // Transaction is rolled back due to session reset, all changes are lost |
| 572 | if (oldFlags & TRA_write) |
| 573 | { |
| 574 | ERR_post_warning(Arg::Warning(isc_ses_reset_warn) << |
| 575 | Arg::Gds(isc_ses_reset_tran_rollback)); |
| 576 | } |
| 577 | |
| 578 | att_initial_options.resetAttachment(this); |
no test coverage detected