DB Backend: convert TransactableHandle to an interface
Created by: camdencheek
This converts TransactableHandle
to an interface and mints three new implementors of the interface: dbHandle
, txHandle
, and savepointHandle
.
The general concept here is to create a TransactableHandle
at startup, then it's a completely opaque type (not strictly yet, but that's the goal). Then, dbHandle.Transact()
returns txHandle
, txHandle.Transact()
returns savepointHandle
, and savepointHandle.Transact()
returns another savepointHandle
.
This design allows us to maintain concrete access to the underlying *sql.DB
and sql.Tx
handles while still providing the opportunity to mock the handle. Additionally, this design completely removes all the required interface casting, unwrapping, and mutation that has been a frequent cause of headaches for people looking at this code (me in particular).
Another thing this will enable is reporting when a transaction is used concurrently. Previously, we would get a random selection of conn busy
, bad connection
, or a panic that was very difficult to debug. This will allow me to lock a transaction during execution and report when a caller tries to use a transaction concurrently.
The new handle types are not constructible yet (unexported and not returned by any public methods). This is intentional because I want this PR to be generally about the design of the new handles and not about implementing their usage. I will migrate tests when I start using them.
Stacked on #37056
Test plan
The new types are unused. Depending on unit tests to verify the correctness of the gopls
renames.