DATA-DOG / go-txdb

Immutable transaction isolated sql driver for golang
Other
667 stars 48 forks source link

Is there any way to support intended rollback? #42

Closed Martin91 closed 7 months ago

Martin91 commented 3 years ago

Background

I am using go-txdb for unit tests in my project, and I expect that I can keep the same status of my database before running each test case. Currently it seems like that go-txdb rollback only when the sql.DB intends to close all driver connections so that it can not meet my requirement.

I have read the code in this repository but can not find any function or method to solve my problem. Have I missed something? If not, I think I can provide a PR to support this.

Proposal: manual rollback support

Besides original rollback strategy, we can add a new method of txdb.txDriver, for example, txDriver.ManualRollback(dsn string), and extract a new method of txdb.conn, for example, conn.Rollback.

txDriver.ManualRollback is responsible for searching the corresponding conn and then delegate the request to conn.Rollback method.

In conn.Rollback, it just needs to do the below 2 steps:

  1. Rollback the underlying db connection;
  2. reset the tx field of conn. That is, it does exactly like the partial of the original conn.Close method, see https://github.com/DATA-DOG/go-txdb/blob/8216b38c0107cac8482c3d8a1b672295d162ae6d/db.go#L183-L186

Besides, we need to make txdb.Register returns the txdb.txDriver instance to the caller so that the latter is possible to call its ManualRollback method.

RobbieZhao commented 1 year ago
l3pp4rd commented 10 months ago

I personally do not advise to support such pattern. where multiple different tests depend on the state of a previous test or similar. Txdb should be used to initialize clean database with tables and all default records in, which are required to normally function. As an example, if you have an e-commerce platform, your fresh database could contain lets say order statuses or settings and defaults in. When each test, should start a session on that fresh database and create all records required to test a certain behavior. After it is done, db connection is closed and it is all rolled back to fresh db state as it was before the test. If some data would be kept in that database, it would mean that your test execution will start to depend on the order of tests being executed and lead to unmaintainable test code base, with unpredictable test run results.

For each test to create data required in the database can be abstracted and it is not performance critical since all these operations will be within transaction.

Maybe you have a certain use case and care to explain it in more detail to see the reasoning behind it?

Martin91 commented 7 months ago

Your suggestion makes sense.