| 1364 | |
| 1365 | |
| 1366 | void TRA_rollback(thread_db* tdbb, jrd_tra* transaction, const bool retaining_flag, |
| 1367 | const bool force_flag) |
| 1368 | { |
| 1369 | /************************************** |
| 1370 | * |
| 1371 | * T R A _ r o l l b a c k |
| 1372 | * |
| 1373 | ************************************** |
| 1374 | * |
| 1375 | * Functional description |
| 1376 | * Rollback a transaction. |
| 1377 | * |
| 1378 | **************************************/ |
| 1379 | SET_TDBB(tdbb); |
| 1380 | |
| 1381 | TraceTransactionEnd trace(transaction, false, retaining_flag); |
| 1382 | |
| 1383 | EDS::Transaction::jrdTransactionEnd(tdbb, transaction, false, retaining_flag, false /*force_flag ?*/); |
| 1384 | |
| 1385 | Jrd::ContextPoolHolder context(tdbb, transaction->tra_pool); |
| 1386 | |
| 1387 | if (transaction->tra_flags & (TRA_prepare2 | TRA_reconnected)) |
| 1388 | MET_update_transaction(tdbb, transaction, false); |
| 1389 | |
| 1390 | // If force flag is true, get rid of all savepoints to mark the transaction as dead |
| 1391 | if (force_flag || (transaction->tra_flags & TRA_invalidated)) |
| 1392 | { |
| 1393 | // Free all savepoint data |
| 1394 | // Undo data space and BLOBs will be released in destructor |
| 1395 | Savepoint::destroy(transaction->tra_save_point); |
| 1396 | fb_assert(!transaction->tra_save_point); |
| 1397 | } |
| 1398 | else if (!retaining_flag) |
| 1399 | { |
| 1400 | // Remove undo data for GTT ON COMMIT DELETE ROWS as their data will be released |
| 1401 | // at transaction end anyway and we don't need to waste time backing it out |
| 1402 | |
| 1403 | for (Savepoint::Iterator iter(transaction->tra_save_point); *iter; ++iter) |
| 1404 | (*iter)->cleanupTempData(); |
| 1405 | } |
| 1406 | |
| 1407 | int state = tra_dead; |
| 1408 | |
| 1409 | if (transaction->tra_save_point) |
| 1410 | { |
| 1411 | // Make sure that any error during savepoint undo is handled by marking |
| 1412 | // the transaction as dead. |
| 1413 | |
| 1414 | try |
| 1415 | { |
| 1416 | // Release all user savepoints except transaction one |
| 1417 | // It will clean up blob ids and temporary space anyway but faster than rollback |
| 1418 | // because record data won't be updated with intermediate versions |
| 1419 | while (transaction->tra_save_point && !transaction->tra_save_point->isRoot()) |
| 1420 | { |
| 1421 | REPL_save_cleanup(tdbb, transaction, transaction->tra_save_point, true); |
| 1422 | transaction->tra_save_point = transaction->tra_save_point->rollforward(tdbb); |
| 1423 | } |
no test coverage detected