GORM Playground Link
https://github.com/go-gorm/playground/pull/482
Description
It appears that nested transactions aren't supported using the manual db.Begin/db.Commit transaction methods, and are only supported using the db.Transaction(function(... block style of transactions.
I'm using transactions in my unit test suite to provide per-test data isolation. I have a test suite type:
type TestSuite {
DB *gorm.DB
...
}
And I have SetupTest and AfterTest functions on that suite that run before and after each test to open and rollback a DB transaction to isolate the test:
func (suite *TestSuite) BeforeTest() {
...
suite.DB = db.Begin()
}
func (suite *TestSuite) AfterTest() {
...
suite.DB.Rollback()
}
Within the application code exercised by the tests I need to use DB transactions, also using the db.Begin/db.Close method. When that code is run as a nested transaction by the test suite the DB interactions all fail with ErrInvalidTransaction when I would assume they would work correctly due to Gorm's support for nested transactions
Comment From: a631807682
https://gorm.io/docs/transactions.html#SavePoint-RollbackTo
Begin means start transaction, you should use SavePoint.
Comment From: mnussbaum
@a631807682 I can switch to using save point, but it seems like this is at least a documentation bug. The docs here say:
GORM supports nested transactions, you can rollback a subset of operations performed within the scope of a larger transaction
But in reality it seems that Gorm only supports nested transactions with the transaction block invocation pattern.
I do see that db.Transaction uses SavePoint internally to implement the nested rollbacks. Logically there's no reason why db.Begin/db.Commit/db.Rollback couldn't also internally use SavePoint to properly implement nested transactions, no?
Comment From: a631807682
@mnussbaum I think this is the problem described by the documentation, because from sql semantics we shouldn't support it in db.Begin.
Can you create a PR to fix the doc?