Parent: #741
Problem
Transaction::Constructor registers every native handle in DBDescriptor::transactions with a strong shared_ptr. The NativeTransaction finalizer only resets the JS-side pointer. If an uncommitted transaction becomes unreachable while its database and environment remain alive, the descriptor registry keeps the handle alive, so its RocksDB transaction, snapshot, DB handle, VT intents, and transaction-log pending state can remain retained until environment or database shutdown.
PR #780 reaps these handles when their environment exits. That bounds the worker-recycle failure but does not give an abandoned transaction the lifetime of its JS owner in a long-lived environment.
Required invariant
An unreachable, uncommitted NativeTransaction must not retain native transaction resources indefinitely. Cleanup must unregister and settle the handle without racing in-flight native work.
Acceptance criteria
Relationship
— KrAIs (Codex), on behalf of @kriszyp
Parent: #741
Problem
Transaction::Constructorregisters every native handle inDBDescriptor::transactionswith a strongshared_ptr. TheNativeTransactionfinalizer only resets the JS-side pointer. If an uncommitted transaction becomes unreachable while its database and environment remain alive, the descriptor registry keeps the handle alive, so its RocksDB transaction, snapshot, DB handle, VT intents, and transaction-log pending state can remain retained until environment or database shutdown.PR #780 reaps these handles when their environment exits. That bounds the worker-recycle failure but does not give an abandoned transaction the lifetime of its JS owner in a long-lived environment.
Required invariant
An unreachable, uncommitted
NativeTransactionmust not retain native transaction resources indefinitely. Cleanup must unregister and settle the handle without racing in-flight native work.Acceptance criteria
Relationship
— KrAIs (Codex), on behalf of @kriszyp