Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

database/sql: Transaction commit closes the transaction even if there was an error on commit. #7777

Closed
gopherbot opened this issue Apr 14, 2014 · 5 comments

Comments

@gopherbot
Copy link

by Thetawaves:

What steps reproduce the problem?
If possible, include a link to a program on play.golang.org.

1. Using the sqlite driver, start a long running query.
2. Attempt to insert a row into the same table you queried.
3. Attempt to commit the insert transaction. The commit will fail because of a lock on
the table.

This is fine except that the transaction commit function in database/sql closes the
database/sql transaction through the use of defer tx.close() even if the commit was
unsuccessful. I have not been able to regain control of this transaction once the
database/sql representation has closed.


What should have happened instead?

The database/sql transaction commit function should first attempt to commit the driver
transaction, and only if it has succeeded, close the database/sql representation.

The function in question:

  1058  // Commit commits the transaction.
  1059  func (tx *Tx) Commit() error {
  1060      if tx.done {
  1061          return ErrTxDone
  1062      }
  1063      defer tx.close()
  1064      tx.dc.Lock()
  1065      defer tx.dc.Unlock()
  1066      return tx.txi.Commit()
  1067  }
@gopherbot
Copy link
Author

Comment 1:

CL https://golang.org/cl/89510043 mentions this issue.

@minux
Copy link
Member

minux commented Apr 19, 2014

Comment 2:

http://golang.org/pkg/database/sql/#Tx:A transaction must end with a call to Commit or
Rollback.
After a call to Commit or Rollback, all operations on the transaction fail with
ErrTxDone.

Status changed to WorkingAsIntended.

@gopherbot
Copy link
Author

Comment 3 by Thetawaves:

If the commit fails in the driver, the underlying transaction in the database still
exists. In Sqlite, you can not start a new transaction while one is already in progress
so this effectively locks out the connection. I suppose you could execute a raw 'COMMIT'
query to close this transaction but I find that idea to be quite silly.

@minux
Copy link
Member

minux commented Apr 20, 2014

Comment 4:

what do you mean?
The code as it stands implements what the docs says about Tx, so
this is not a bug. If you still think it's a bug, then you will need to
address any dependencies on this rule before propose a change to
it. In the CL discussion, lib/pq is said to depend on this assumption
already, so it's very unlikely we want to change the behavior and
break existing drivers.

@alexbrainman
Copy link
Member

Comment 5:

Thetawaves,
Please provide small program to demonstrate "your problem". Tell us what your program
does, and explain why it should behave differently. It is difficult to make a judgement
without clear understanding the problem. Perhaps it is something driver should do. You
need to convince everyone here that database/sql has to change. Thank you.
Alex

@golang golang locked and limited conversation to collaborators Jun 25, 2016
This issue was closed.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants