Fossil SCM
Avoid database locking errors caused by db_optional_sql() writes.
Commit
b22cc4eb73c34401d74d76627de229e6bb4c5f10
Parent
7fb59a67dc6ecf1…
2 files changed
+4
-2
+1
-1
M
src/db.c
+4
-2
| --- src/db.c | ||
| +++ src/db.c | ||
| @@ -117,10 +117,11 @@ | ||
| 117 | 117 | int sequence; /* Call functions in sequence order */ |
| 118 | 118 | } aHook[5]; |
| 119 | 119 | char *azDeleteOnFail[3]; /* Files to delete on a failure */ |
| 120 | 120 | char *azBeforeCommit[5]; /* Commands to run prior to COMMIT */ |
| 121 | 121 | int nBeforeCommit; /* Number of entries in azBeforeCommit */ |
| 122 | + int nPriorChanges; /* sqlite3_total_changes() at transaction start */ | |
| 122 | 123 | } db = {0, 0, 0, 0, 0, 0, }; |
| 123 | 124 | |
| 124 | 125 | /* |
| 125 | 126 | ** Arrange for the given file to be deleted on a failure. |
| 126 | 127 | */ |
| @@ -151,10 +152,11 @@ | ||
| 151 | 152 | */ |
| 152 | 153 | void db_begin_transaction(void){ |
| 153 | 154 | if( db.nBegin==0 ){ |
| 154 | 155 | db_multi_exec("BEGIN"); |
| 155 | 156 | sqlite3_commit_hook(g.db, db_verify_at_commit, 0); |
| 157 | + db.nPriorChanges = sqlite3_total_changes(g.db); | |
| 156 | 158 | } |
| 157 | 159 | db.nBegin++; |
| 158 | 160 | } |
| 159 | 161 | void db_end_transaction(int rollbackFlag){ |
| 160 | 162 | if( g.db==0 ) return; |
| @@ -161,14 +163,14 @@ | ||
| 161 | 163 | if( db.nBegin<=0 ) return; |
| 162 | 164 | if( rollbackFlag ) db.doRollback = 1; |
| 163 | 165 | db.nBegin--; |
| 164 | 166 | if( db.nBegin==0 ){ |
| 165 | 167 | int i; |
| 166 | - if( db.doRollback==0 ){ | |
| 168 | + if( db.doRollback==0 && db.nPriorChanges<sqlite3_total_changes(g.db) ){ | |
| 167 | 169 | while( db.nBeforeCommit ){ |
| 168 | 170 | db.nBeforeCommit--; |
| 169 | - db_multi_exec(db.azBeforeCommit[db.nBeforeCommit]); | |
| 171 | + sqlite3_exec(g.db, db.azBeforeCommit[db.nBeforeCommit], 0, 0, 0); | |
| 170 | 172 | sqlite3_free(db.azBeforeCommit[db.nBeforeCommit]); |
| 171 | 173 | } |
| 172 | 174 | leaf_do_pending_checks(); |
| 173 | 175 | } |
| 174 | 176 | for(i=0; db.doRollback==0 && i<db.nCommitHook; i++){ |
| 175 | 177 |
| --- src/db.c | |
| +++ src/db.c | |
| @@ -117,10 +117,11 @@ | |
| 117 | int sequence; /* Call functions in sequence order */ |
| 118 | } aHook[5]; |
| 119 | char *azDeleteOnFail[3]; /* Files to delete on a failure */ |
| 120 | char *azBeforeCommit[5]; /* Commands to run prior to COMMIT */ |
| 121 | int nBeforeCommit; /* Number of entries in azBeforeCommit */ |
| 122 | } db = {0, 0, 0, 0, 0, 0, }; |
| 123 | |
| 124 | /* |
| 125 | ** Arrange for the given file to be deleted on a failure. |
| 126 | */ |
| @@ -151,10 +152,11 @@ | |
| 151 | */ |
| 152 | void db_begin_transaction(void){ |
| 153 | if( db.nBegin==0 ){ |
| 154 | db_multi_exec("BEGIN"); |
| 155 | sqlite3_commit_hook(g.db, db_verify_at_commit, 0); |
| 156 | } |
| 157 | db.nBegin++; |
| 158 | } |
| 159 | void db_end_transaction(int rollbackFlag){ |
| 160 | if( g.db==0 ) return; |
| @@ -161,14 +163,14 @@ | |
| 161 | if( db.nBegin<=0 ) return; |
| 162 | if( rollbackFlag ) db.doRollback = 1; |
| 163 | db.nBegin--; |
| 164 | if( db.nBegin==0 ){ |
| 165 | int i; |
| 166 | if( db.doRollback==0 ){ |
| 167 | while( db.nBeforeCommit ){ |
| 168 | db.nBeforeCommit--; |
| 169 | db_multi_exec(db.azBeforeCommit[db.nBeforeCommit]); |
| 170 | sqlite3_free(db.azBeforeCommit[db.nBeforeCommit]); |
| 171 | } |
| 172 | leaf_do_pending_checks(); |
| 173 | } |
| 174 | for(i=0; db.doRollback==0 && i<db.nCommitHook; i++){ |
| 175 |
| --- src/db.c | |
| +++ src/db.c | |
| @@ -117,10 +117,11 @@ | |
| 117 | int sequence; /* Call functions in sequence order */ |
| 118 | } aHook[5]; |
| 119 | char *azDeleteOnFail[3]; /* Files to delete on a failure */ |
| 120 | char *azBeforeCommit[5]; /* Commands to run prior to COMMIT */ |
| 121 | int nBeforeCommit; /* Number of entries in azBeforeCommit */ |
| 122 | int nPriorChanges; /* sqlite3_total_changes() at transaction start */ |
| 123 | } db = {0, 0, 0, 0, 0, 0, }; |
| 124 | |
| 125 | /* |
| 126 | ** Arrange for the given file to be deleted on a failure. |
| 127 | */ |
| @@ -151,10 +152,11 @@ | |
| 152 | */ |
| 153 | void db_begin_transaction(void){ |
| 154 | if( db.nBegin==0 ){ |
| 155 | db_multi_exec("BEGIN"); |
| 156 | sqlite3_commit_hook(g.db, db_verify_at_commit, 0); |
| 157 | db.nPriorChanges = sqlite3_total_changes(g.db); |
| 158 | } |
| 159 | db.nBegin++; |
| 160 | } |
| 161 | void db_end_transaction(int rollbackFlag){ |
| 162 | if( g.db==0 ) return; |
| @@ -161,14 +163,14 @@ | |
| 163 | if( db.nBegin<=0 ) return; |
| 164 | if( rollbackFlag ) db.doRollback = 1; |
| 165 | db.nBegin--; |
| 166 | if( db.nBegin==0 ){ |
| 167 | int i; |
| 168 | if( db.doRollback==0 && db.nPriorChanges<sqlite3_total_changes(g.db) ){ |
| 169 | while( db.nBeforeCommit ){ |
| 170 | db.nBeforeCommit--; |
| 171 | sqlite3_exec(g.db, db.azBeforeCommit[db.nBeforeCommit], 0, 0, 0); |
| 172 | sqlite3_free(db.azBeforeCommit[db.nBeforeCommit]); |
| 173 | } |
| 174 | leaf_do_pending_checks(); |
| 175 | } |
| 176 | for(i=0; db.doRollback==0 && i<db.nCommitHook; i++){ |
| 177 |
+1
-1
| --- src/main.c | ||
| +++ src/main.c | ||
| @@ -1093,11 +1093,11 @@ | ||
| 1093 | 1093 | }else{ |
| 1094 | 1094 | g.zBaseURL = mprintf("http://%s%.*s", zHost, i, zCur); |
| 1095 | 1095 | g.zTop = &g.zBaseURL[7+strlen(zHost)]; |
| 1096 | 1096 | } |
| 1097 | 1097 | if( db_is_writeable("repository") ){ |
| 1098 | - if( !db_exists("SELECT 1 FROM config WHERE name='baseurl:%q'", g.zBaseURL) ){ | |
| 1098 | + if( !db_exists("SELECT 1 FROM config WHERE name='baseurl:%q'", g.zBaseURL)){ | |
| 1099 | 1099 | db_multi_exec("INSERT INTO config(name,value,mtime)" |
| 1100 | 1100 | "VALUES('baseurl:%q',1,now())", g.zBaseURL); |
| 1101 | 1101 | }else{ |
| 1102 | 1102 | db_optional_sql("repository", |
| 1103 | 1103 | "REPLACE INTO config(name,value,mtime)" |
| 1104 | 1104 |
| --- src/main.c | |
| +++ src/main.c | |
| @@ -1093,11 +1093,11 @@ | |
| 1093 | }else{ |
| 1094 | g.zBaseURL = mprintf("http://%s%.*s", zHost, i, zCur); |
| 1095 | g.zTop = &g.zBaseURL[7+strlen(zHost)]; |
| 1096 | } |
| 1097 | if( db_is_writeable("repository") ){ |
| 1098 | if( !db_exists("SELECT 1 FROM config WHERE name='baseurl:%q'", g.zBaseURL) ){ |
| 1099 | db_multi_exec("INSERT INTO config(name,value,mtime)" |
| 1100 | "VALUES('baseurl:%q',1,now())", g.zBaseURL); |
| 1101 | }else{ |
| 1102 | db_optional_sql("repository", |
| 1103 | "REPLACE INTO config(name,value,mtime)" |
| 1104 |
| --- src/main.c | |
| +++ src/main.c | |
| @@ -1093,11 +1093,11 @@ | |
| 1093 | }else{ |
| 1094 | g.zBaseURL = mprintf("http://%s%.*s", zHost, i, zCur); |
| 1095 | g.zTop = &g.zBaseURL[7+strlen(zHost)]; |
| 1096 | } |
| 1097 | if( db_is_writeable("repository") ){ |
| 1098 | if( !db_exists("SELECT 1 FROM config WHERE name='baseurl:%q'", g.zBaseURL)){ |
| 1099 | db_multi_exec("INSERT INTO config(name,value,mtime)" |
| 1100 | "VALUES('baseurl:%q',1,now())", g.zBaseURL); |
| 1101 | }else{ |
| 1102 | db_optional_sql("repository", |
| 1103 | "REPLACE INTO config(name,value,mtime)" |
| 1104 |