| 745 | } |
| 746 | |
| 747 | void DsqlDmlRequest::executeReceiveWithRestarts(thread_db* tdbb, jrd_tra** traHandle, |
| 748 | IMessageMetadata* outMetadata, UCHAR* outMsg, |
| 749 | bool singleton, bool exec, bool fetch) |
| 750 | { |
| 751 | request->req_flags &= ~req_update_conflict; |
| 752 | int numTries = 0; |
| 753 | const int MAX_RESTARTS = 10; |
| 754 | |
| 755 | while (true) |
| 756 | { |
| 757 | AutoSavePoint savePoint(tdbb, req_transaction); |
| 758 | |
| 759 | // Don't set req_restart_ready flag at last attempt to restart request. |
| 760 | // It allows to raise update conflict error (if any) as usual and |
| 761 | // handle error by PSQL handler. |
| 762 | const ULONG flag = (numTries >= MAX_RESTARTS) ? 0 : req_restart_ready; |
| 763 | AutoSetRestoreFlag<ULONG> restartReady(&request->req_flags, flag, true); |
| 764 | try |
| 765 | { |
| 766 | if (exec) |
| 767 | doExecute(tdbb, traHandle, outMetadata, outMsg, singleton); |
| 768 | |
| 769 | if (fetch) |
| 770 | { |
| 771 | fb_assert(dsqlStatement->isCursorBased()); |
| 772 | |
| 773 | const dsql_msg* message = dsqlStatement->getReceiveMsg(); |
| 774 | |
| 775 | UCHAR* dsqlMsgBuffer = req_msg_buffers[message->msg_buffer_number]; |
| 776 | JRD_receive(tdbb, request, message->msg_number, message->msg_length, dsqlMsgBuffer); |
| 777 | } |
| 778 | } |
| 779 | catch (const status_exception&) |
| 780 | { |
| 781 | if (!(req_transaction->tra_flags & TRA_ex_restart)) |
| 782 | { |
| 783 | request->req_flags &= ~req_update_conflict; |
| 784 | throw; |
| 785 | } |
| 786 | } |
| 787 | |
| 788 | if (!(request->req_flags & req_update_conflict)) |
| 789 | { |
| 790 | fb_assert((req_transaction->tra_flags & TRA_ex_restart) == 0); |
| 791 | req_transaction->tra_flags &= ~TRA_ex_restart; |
| 792 | |
| 793 | #ifdef DEV_BUILD |
| 794 | if (numTries > 0) |
| 795 | { |
| 796 | string s; |
| 797 | s.printf("restarts = %d", numTries); |
| 798 | |
| 799 | ERRD_post_warning(Arg::Warning(isc_random) << Arg::Str(s)); |
| 800 | } |
| 801 | #endif |
| 802 | savePoint.release(); // everything is ok |
| 803 | break; |
| 804 | } |
nothing calls this directly
no test coverage detected