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?