-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
inconsistent transaction state #184
Comments
Could you please show me the small code to reproduce? |
Here's my original code snippet: REMIND:When commit transaction periodically, /usr/bin/sqlite3 will do a big query and the commit will fail. Here's modified code snippet: Here's the Close-Then-ReOpen workaround I'm not satisfied: |
@mattn What can I do for you? |
I'm thinking either of program should be given a BUSY or LOCKED at commit time. |
How the bug progress? |
Could you please try https://github.com/mattn/go-sqlite3/blob/master/sqlite3.go#L274 Set bigger value like |
When timeout, could I fail the current transaction and begin another transaction without reopen db? |
Do you know where the timeout occured? Commit? Exec? |
Almost commit, I guess, because it's the most time-consuming operation, isn't it ? And _busy_timeout's unit ? ms or us ? |
ms
I must check which is occured timeout. |
Could you please minimum test case that can reproduce? |
No matter what I set timeout is, I have to reopen db when transaction fail, right ? |
I want to check whether this behavior should be fixed or not. |
hi @xrtgavin Here is what i solve the func (s *Meyovoter) InsertFormVoterList(mid int64, ids []int64) error {
tx, err := s.db.Begin()
if err != nil {
return err
}
str := fmt.Sprintf("INSERT INTO %s ( `meyo_id`, `voter_id`) VALUES (?, ?);", meyo_voter_table)
stmt, err := tx.Prepare(str)
if err != nil {
return err
}
defer stmt.Close()
for _, id := range ids {
_, err = stmt.Exec(mid, id)
if err != nil {
tx.Rollback() // This line is the key.
return err
}
}
if err := tx.Commit(); err != nil {
return tx.Rollback()
}
return nil
} |
@xeodou Rollback() does not make sense to the problem. See my problem again. |
oh, Sorry. @xrtgavin |
Hi guys, |
@ea-at-diladele-com AFAIK,no any process |
@xrtgavin wrote:
You are wrong from sqlite's perspective. See https://www.sqlite.org/lang_transaction.html:
However you are correct from This is the source of the inconsistency; as far as the database package is concerned the transaction is done, so any further attempts to commit/rollback are met with the error "sql: Transaction has already been committed or rolled back" without consulting the sqlite3 driver. There's two ways to proceed:
Option 2 is more flexible in that it allows the user to decide whether they want to retry the COMMIT at a later time, but it also kind of defeats the purpose of using the |
@sqweek Appreciate your insight about the issue. Thank you. |
The semantics of sql.Tx.Commit impose that the transaction is finished and cleaned up by the time the driver's Commit function returns. However sqlite3 leaves the transaction open if COMMIT fails due to an SQLITE_BUSY error, so *we* must clean it up. Closes mattn#184.
I think option 1 is the right solution; it seems like the only way to provide consistent behaviour via the Users who really really want to keep retrying COMMIT upon SQLITE_BUSY can either:
|
First of all,I open the db file in the following way.
My program commit a db transaction periodically. At the same time, another program(like /usr/bin/sqlite3) do a big query on the same db. Then error reported is:
IMO, a fail-commited transaction means a rollbacked transaction. Am I wrong ?
I do the rollback manually. And error reported became:
Now, I‘m confusing. What should I do to begin a new transaction? The old transaction is rolled back, OR NOT?
Do not inform me: Close-Then-ReOpen the db. It's just a workaround.
Finally I need help and also want to help.
The text was updated successfully, but these errors were encountered: