Commit
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -463,12 +463,14 @@ func (r *SQLiteResult) RowsAffected() (int64, error) { | |
func (s *SQLiteStmt) Exec(args []driver.Value) (driver.Result, error) { | ||
if err := s.bind(args); err != nil { | ||
C.sqlite3_reset(s.s) | ||
C.sqlite3_clear_bindings(s.s) | ||
return nil, err | ||
} | ||
rv := C.sqlite3_step(s.s) | ||
if rv != C.SQLITE_ROW && rv != C.SQLITE_OK && rv != C.SQLITE_DONE { | ||
err := s.c.lastError() | ||
C.sqlite3_reset(s.s) | ||
C.sqlite3_clear_bindings(s.s) | ||
return nil, err | ||
} | ||
|
||
|
@@ -507,16 +509,22 @@ func (rc *SQLiteRows) Columns() []string { | |
|
||
// Move cursor to next. | ||
func (rc *SQLiteRows) Next(dest []driver.Value) error { | ||
rv := C.sqlite3_step(rc.s.s) | ||
if rv == C.SQLITE_DONE { | ||
return io.EOF | ||
} | ||
if rv != C.SQLITE_ROW { | ||
rv = C.sqlite3_reset(rc.s.s) | ||
if rv != C.SQLITE_OK { | ||
return rc.s.c.lastError() | ||
for { | ||
rv := C.sqlite3_step(rc.s.s) | ||
if rv == C.SQLITE_DONE { | ||
return io.EOF | ||
} | ||
if rv == C.SQLITE_ROW { | ||
break | ||
} | ||
if rv != C.SQLITE_BUSY && rv != C.SQLITE_LOCKED { | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
gwenn
|
||
err := rc.s.c.lastError() | ||
C.sqlite3_reset(rc.s.s) | ||
if rc.nc > 0 { | ||
C.sqlite3_clear_bindings(rc.s.s) | ||
} | ||
return err | ||
} | ||
return nil | ||
} | ||
|
||
if rc.decltype == nil { | ||
|
10 comments
on commit 5253daf
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@gwenn, I think he meant a PR to revert this commit. (Too bad about the extra boilerplate in all callers, but indeed it looks like this commit isn't needed or appropriate then - at least unless/until sqlite3 offers automatic retry-until-not-locked-with-timeout).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But I'm thinking go-sqlite3 can retry if query parameter in DSN is set.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe I am wrong but the driver should not retry indefinitely by default.
You can increase the busy timeout (by calling sqlite3_busy_timeout).
Or you can attach a custom sqlite3_busy_handler which never returns zero.
For SQLITE_LOCKED, the problem still remains.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In few days ago, I received e-mail from someone. He says: 'we must write code to retry for sqlite3'. So we decide to change.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Retries are already done by sqlite3_busy_timeout...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, okay. I'll provide way to change the value of sqlite3_busy_timeout.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
http://sqlite.1065341.n5.nabble.com/sqlite3-busy-timeout-tp2711p2712.html
But if you set up sqlite3_busy_timeout, SQLite will automatically retry your
operation several times before erroring out. Hopefully the writing
transaction completes before the timeout has expired, and your select is
allowed to proceed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do it works against SQLITE_LOCKED also?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll revert this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, sqlite_busy_* doesn't work against SQLITE_LOCKED. But SQLITE_LOCKED should not happen with database/sql
except in shared cache mode.
http://sqlite.org/c3ref/step.html:
SQLITE_BUSY means that the database engine was unable to acquire the database locks it needs to do its job. If the statement is a COMMIT or occurs outside of an explicit transaction, then you can retry the statement. If the statement is not a COMMIT and occurs within an explicit transaction then you should rollback the transaction before continuing.