To be clear, I'm not saying you can't handle database problems. If there are situations where a recovery path is possible and worth the effort then by all means do that (that becomes an expected error now*). However, in a lot of cases it's not possible or simply not worth it since a retry mechanism is almost always better situated outside the request, job, etc entirely. So, fail fast (panic) within the unit of work itself. I explain more about his in my response to Danilkin.
To your point about handling errors explicitly to invoke a rollback. Well, you still need a panic recover anyway since you can never guarantee that the application will not fail outside of your control during the TX. A divide by zero, or a panic from the Go stdlib, for example.
I believe the panic gives great context because you always have a full stack trace. Unlike errors, which if you forget to wrap them with pkg/errors or manually prefix them at every single point up the chain the visibility is much worse than a panic.
* I'm not that happy with the terminology I have used and tend to use "unexpected" and "unresolvable" interchangeably. Unexpected doesn't mean something that can't happen, but rather a type of error where we have no reasonable recourse for.