]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Another approach at implementing COMMIT AND BEGIN.
authordrh <>
Fri, 15 Nov 2024 17:28:57 +0000 (17:28 +0000)
committerdrh <>
Fri, 15 Nov 2024 17:28:57 +0000 (17:28 +0000)
FossilOrigin-Name: a905bd5dd6ccb6f2e5671a5b691e61c853aa425e6a53e7e6b6dbc12e4020ef14

13 files changed:
manifest
manifest.uuid
src/backup.c
src/btree.c
src/btree.h
src/pager.c
src/pager.h
src/sqliteInt.h
src/test2.c
src/vdbe.c
src/vdbeaux.c
src/wal.c
src/wal.h

index 786a1241e2295873d8ce1c3705448d97abc4097a..dbb1abe4271e301b7d1636b116f71977f8891896 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Attempt\sto\shold\sa\slock\sacross\sthe\sCOMMIT\sAND\sBEGIN\sboundary\sso\sthat\sno\sother\nprocess\scan\sstart\sa\snew\stransaction\sin\sbetween\sthe\sCOMMIT\sand\sthe\sBEGIN.
-D 2024-11-14T22:59:16.150
+C Another\sapproach\sat\simplementing\sCOMMIT\sAND\sBEGIN.
+D 2024-11-15T17:28:57.110
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d
@@ -710,11 +710,11 @@ F src/alter.c aa93e37e4a36a0525bbb2a2aeda20d2018f0aa995542c7dc658e031375e3f532
 F src/analyze.c 9a8b67239d899ac12289db5db3f5bfe7f7a0ad1277f80f87ead1d048085876eb
 F src/attach.c f35bb8cc1fcdde8f6815a7ef09ae413bcac71821d530796800ba24b3c7da1e80
 F src/auth.c 54ab9c6c5803b47c0d45b76ce27eff22a03b4b1f767c5945a3a4eb13aa4c78dc
-F src/backup.c 3a6b733262d0c8177fce98ae3a52b7bcbcec52e8f99f5aa0c7f08da35b1286b8
+F src/backup.c 5c97e8023aab1ce14a42387eb3ae00ba5a0644569e3476f38661fa6f824c3523
 F src/bitvec.c 9eac5f42c11914d5ef00a75605bb205e934f435c579687f985f1f8b0995c8645
 F src/btmutex.c 79a43670447eacc651519a429f6ece9fd638563cf95b469d6891185ddae2b522
-F src/btree.c b1027870704ab6a80c5c5e81f16a592562debf2600c4f2e3d2d8715664d830d0
-F src/btree.h 86f2a22eb71024ee5dc3d0125c7cac62c8fab75583182bff082ea4e9a58dd125
+F src/btree.c 63ca6b647342e8cef643863cd0962a542f133e1069460725ba4461dcda92b03c
+F src/btree.h 18e5e7b2124c23426a283523e5f31a4bff029131b795bb82391f9d2f3136fc50
 F src/btreeInt.h 98aadb6dcb77b012cab2574d6a728fad56b337fc946839b9898c4b4c969e30b6
 F src/build.c c219c01d3490420addfe5e9673ed136cbf89acf4c72370b548cf68a4ad5cc281
 F src/callback.c db3a45e376deff6a16c0058163fe0ae2b73a2945f3f408ca32cf74960b28d490
@@ -761,8 +761,8 @@ F src/os_setup.h 6011ad7af5db4e05155f385eb3a9b4470688de6f65d6166b8956e58a3d87210
 F src/os_unix.c d2edbd92b07a3f778c2defa8a2e9d75acceb6267bda56948c41e8cdda65224d6
 F src/os_win.c db4baa8f62bbfe3967c71b008cea31a8f2ff337c1667ff4d8a677e697315ff0d
 F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a
-F src/pager.c 6b3929ef6aa958a991967f03de56a258b41ff34a11670d6ca388e1a35af0c6ae
-F src/pager.h dea3f0dc42b12dc07596e4d92bae1a6ef9d7320ab7683f57ddcedf8294205417
+F src/pager.c 6d5d8ebe7e0fbaa5ad8c6b327e17271334b99e887b871df667a79b71215acfc7
+F src/pager.h 87f5995a18a11130c52d20c9556da02cdfe40ffd7daaa43ca0fcd922d83b7257
 F src/parse.y 61033fb5fa609161a0025fe7b6941ee5afbf382f6927ea26c51892dd3b63d731
 F src/pcache.c 588cc3c5ccaaadde689ed35ce5c5c891a1f7b1f4d1f56f6cf0143b74d8ee6484
 F src/pcache.h 1497ce1b823cf00094bb0cf3bac37b345937e6f910890c626b16512316d3abf5
@@ -779,14 +779,14 @@ F src/shell.c.in c61d7af58e678d479f1450e4ea236d2d6ac3bb16a636030104f210303b30d56
 F src/sqlite.h.in 4d93768709c53b7c653a63817a82d5a8625264ca0d8cdf99967ba147bdcf2aa6
 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
 F src/sqlite3ext.h 3f046c04ea3595d6bfda99b781926b17e672fd6d27da2ba6d8d8fc39981dcb54
-F src/sqliteInt.h ba5f56d3ba50e2b86cc2d11599c141ad84f90b85e1d272913d1bd92bd2469bb6
+F src/sqliteInt.h 08735a5db1be299c3478ceb03d63729c1c7c4fe1ba82ac7b724535098c86bfa7
 F src/sqliteLimit.h 6993c9cfe3af5b8169ae0e5f15627fc15596726d4f1dc90a221309f79715ce88
 F src/status.c cb11f8589a6912af2da3bb1ec509a94dd8ef27df4d4c1a97e0bcf2309ece972b
 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1
 F src/tclsqlite.c ff2dc3ec1bd318ee7a45d6b246a367703d5fb2a4c8da99d675ee7eb987b3a153
 F src/tclsqlite.h 65e2c761446e1c9fa0342b7d2612a703483643c8b6a316d12a65b745a4727395
 F src/test1.c 2d507751bfb4aa254dc22588ef1e3c5c5cfcb2e636d0e6e1fa0bbd307669c2a8
-F src/test2.c 1d7928a9aa9576d6e153f219b841363782939eec6750866bc748b371a4bbadde
+F src/test2.c 7ebc518e6735939d8979273a6f7b1d9b5702babf059f6ad62499f7f60a9eb9a3
 F src/test3.c e7573aa0f78ee4e070a4bc8c3493941c1aa64d5c66d4825c74c0f055451f432b
 F src/test4.c 13e57ae7ec7a959ee180970aef09deed141252fe9bb07c61054f0dfa4f1dfd5d
 F src/test5.c bb87279ed12e199486894e6c83e58dc8cd1de9524ace171d59219d3ab696a0c1
@@ -843,11 +843,11 @@ F src/upsert.c 215328c3f91623c520ec8672c44323553f12caeb4f01b1090ebdca99fdf7b4f1
 F src/utf.c 8b29d9a5956569ea2700f869669b8ef67a9662ee5e724ff77ab3c387e27094ba
 F src/util.c ceebf912f673247e305f16f97f0bb7285fca1d37413b79680714a553a9021d33
 F src/vacuum.c b763b6457bd058d2072ef9364832351fd8d11e8abf70cbb349657360f7d55c40
-F src/vdbe.c f4cb87fa3c12ec151515731badeaa997defa071f677c0f2f2cb52c818a5762b6
+F src/vdbe.c d726c4fc8cca5d960d95b61573920a5f8e8ff5b34734c918680e00e3c6fbf07f
 F src/vdbe.h c2549a215898a390de6669cfa32adba56f0d7e17ba5a7f7b14506d6fd5f0c36a
 F src/vdbeInt.h 2da01c73e8e3736a9015d5b04aa04d209bc9023d279d237d4d409205e921ea1e
 F src/vdbeapi.c 6353de05e8e78e497ccb33381ba5662ccc11c0339e5b1455faff01b6dacc3075
-F src/vdbeaux.c 798d56fc53f833225e5f72adbdf15644faf4035657cc8a4023140fe9238e2ddf
+F src/vdbeaux.c f0706ad786b8a6c5bc7ea622f3916c2ba2b883abc872d0b4911c4f021945c0e5
 F src/vdbeblob.c 255be187436da38b01f276c02e6a08103489bbe2a7c6c21537b7aecbe0e1f797
 F src/vdbemem.c df568ef0187e4be2788c35174f6d9b8566ab9475f9aff2d73907ed05aa5684b2
 F src/vdbesort.c d0a3c7056c081703c8b6d91ad60f17da5e062a5c64bf568ed0fa1b5f4cae311f
@@ -855,8 +855,8 @@ F src/vdbetrace.c fe0bc29ebd4e02c8bc5c1945f1d2e6be5927ec12c06d89b03ef2a4def34bf8
 F src/vdbevtab.c fc46b9cbd759dc013f0b3724549cc0d71379183c667df3a5988f7e2f1bd485f3
 F src/vtab.c 316cd48e9320660db3047cd306cd056e4361180cebb4d0f10a39244e10c11422
 F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
-F src/wal.c 8b7e309a8012659ac9275ad8cdcc6acaf73fa04b1090e38a01335f230fd10681
-F src/wal.h ba252daaa94f889f4b2c17c027e823d9be47ce39da1d3799886bbd51f0490452
+F src/wal.c 75a94c7dca2018f5a0cf65022f3c59661c7d327b324de068e0e1ee1f271d9dd7
+F src/wal.h 3289ab8741f440d675f08448e067028b275774cb29548e6fb4d3ab789ab6e30e
 F src/walker.c d5006d6b005e4ea7302ad390957a8d41ed83faa177e412f89bc5600a7462a014
 F src/where.c 4de9e7ca5f49e4a21c1d733e2b2fbbc8b62b1a157a58a562c569da84cfcb005b
 F src/whereInt.h 1e36ec50392f7cc3d93d1152d4338064cd522b87156a0739388b7e273735f0ca
@@ -2198,8 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350
 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7
 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139
 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
-P a9a4ac17c2169fa7f97434177dfb01eaf4fae7f99b9203677d985d048eea4559
-R e076e0b1d6dcf99285c63f69d8918932
+P bc8bcc53ff7a0cbe1c2e3a96e1bded055622b667c27284798433cc6d58c7f9fe
+R aaebfd24ca9d8f02dfa3d9b4ca914292
 U drh
-Z 102dff9a412a8b8f29da274c5cd5e9d0
+Z 6e111722224488acfb9edbbb67215a33
 # Remove this line to create a well-formed Fossil manifest.
index 4b5cf1d7c3a73ad8f7a7269217c537ee95e3ac51..d0840ad730d0fefe3dbfd134d7d9eb2a0aa28a1e 100644 (file)
@@ -1 +1 @@
-bc8bcc53ff7a0cbe1c2e3a96e1bded055622b667c27284798433cc6d58c7f9fe
+a905bd5dd6ccb6f2e5671a5b691e61c853aa425e6a53e7e6b6dbc12e4020ef14
index 657d9abbb6f82f605fb442acc91f3a305fa32512..22615d1499b54ddf00f4ea8b0f83b804ebbc8ceb 100644 (file)
@@ -533,7 +533,7 @@ int sqlite3_backup_step(sqlite3_backup *p, int nPage){
     
         /* Finish committing the transaction to the destination database. */
         if( SQLITE_OK==rc
-         && SQLITE_OK==(rc = sqlite3BtreeCommitPhaseTwo(p->pDest, 0, 0))
+         && SQLITE_OK==(rc = sqlite3BtreeCommitPhaseTwo(p->pDest, 0))
         ){
           rc = SQLITE_DONE;
         }
@@ -548,7 +548,7 @@ int sqlite3_backup_step(sqlite3_backup *p, int nPage){
     if( bCloseTrans ){
       TESTONLY( int rc2 );
       TESTONLY( rc2  = ) sqlite3BtreeCommitPhaseOne(p->pSrc, 0);
-      TESTONLY( rc2 |= ) sqlite3BtreeCommitPhaseTwo(p->pSrc, 0, 0);
+      TESTONLY( rc2 |= ) sqlite3BtreeCommitPhaseTwo(p->pSrc, 0);
       assert( rc2==SQLITE_OK );
     }
   
index 38abdfee4e34574e039844f1ef1298be52c269bc..49eb1d803788eeef461cedc0731af311cd38c2b4 100644 (file)
@@ -4353,7 +4353,7 @@ static void btreeEndTransaction(Btree *p){
 ** This will release the write lock on the database file.  If there
 ** are no active cursors, it also releases the read lock.
 */
-int sqlite3BtreeCommitPhaseTwo(Btree *p, int bCleanup, int bKeepLock){
+int sqlite3BtreeCommitPhaseTwo(Btree *p, int bCleanup){
 
   if( p->inTrans==TRANS_NONE ) return SQLITE_OK;
   sqlite3BtreeEnter(p);
@@ -4367,7 +4367,7 @@ int sqlite3BtreeCommitPhaseTwo(Btree *p, int bCleanup, int bKeepLock){
     BtShared *pBt = p->pBt;
     assert( pBt->inTransaction==TRANS_WRITE );
     assert( pBt->nTransaction>0 );
-    rc = sqlite3PagerCommitPhaseTwo(pBt->pPager, bKeepLock);
+    rc = sqlite3PagerCommitPhaseTwo(pBt->pPager);
     if( rc!=SQLITE_OK && bCleanup==0 ){
       sqlite3BtreeLeave(p);
       return rc;
@@ -4390,7 +4390,7 @@ int sqlite3BtreeCommit(Btree *p){
   sqlite3BtreeEnter(p);
   rc = sqlite3BtreeCommitPhaseOne(p, 0);
   if( rc==SQLITE_OK ){
-    rc = sqlite3BtreeCommitPhaseTwo(p, 0, 0);
+    rc = sqlite3BtreeCommitPhaseTwo(p, 0);
   }
   sqlite3BtreeLeave(p);
   return rc;
index 173ac12ee6524add2ead1ca72f73c19543e85076..241261dc6a19b58c4e7036a305198ff5ba1909bb 100644 (file)
@@ -80,7 +80,7 @@ int sqlite3BtreeSetAutoVacuum(Btree *, int);
 int sqlite3BtreeGetAutoVacuum(Btree *);
 int sqlite3BtreeBeginTrans(Btree*,int,int*);
 int sqlite3BtreeCommitPhaseOne(Btree*, const char*);
-int sqlite3BtreeCommitPhaseTwo(Btree*, int, int);
+int sqlite3BtreeCommitPhaseTwo(Btree*, int);
 int sqlite3BtreeCommit(Btree*);
 int sqlite3BtreeRollback(Btree*,int,int);
 int sqlite3BtreeBeginStmt(Btree*,int);
index 4154561302b90e8f08f4f35bcc3e03f6bb096211..6f98c1d6d07acfb28776d70723a8e72af033c390 100644 (file)
@@ -643,6 +643,7 @@ struct Pager {
   */
   u8 eState;                  /* Pager state (OPEN, READER, WRITER_LOCKED..) */
   u8 eLock;                   /* Current lock held on database file */
+  u8 eMinLock;                /* Minimum lock */
   u8 changeCountDone;         /* Set after incrementing the change-counter */
   u8 setSuper;                /* Super-jrnl name is written into jrnl */
   u8 doNotSpill;              /* Do not spill the cache when non-zero */
@@ -1145,15 +1146,22 @@ static int pagerUnlockDb(Pager *pPager, int eLock){
   assert( !pPager->exclusiveMode || pPager->eLock==eLock );
   assert( eLock==NO_LOCK || eLock==SHARED_LOCK );
   assert( eLock!=NO_LOCK || pagerUseWal(pPager)==0 );
+  pPager->changeCountDone = pPager->tempFile; /* ticket fb3b3024ea238d5c */
   if( isOpen(pPager->fd) ){
     assert( pPager->eLock>=eLock );
+    if( pPager->eMinLock ){
+      if( eLock<SHARED_LOCK ) eLock = SHARED_LOCK;
+      if( pPager->eMinLock==2 && eLock<EXCLUSIVE_LOCK ) eLock = EXCLUSIVE_LOCK;
+      if( eLock>=pPager->eLock ){
+        return SQLITE_OK;
+      }
+    }
     rc = pPager->noLock ? SQLITE_OK : sqlite3OsUnlock(pPager->fd, eLock);
     if( pPager->eLock!=UNKNOWN_LOCK ){
       pPager->eLock = (u8)eLock;
     }
     IOTRACE(("UNLOCK %p %d\n", pPager, eLock))
   }
-  pPager->changeCountDone = pPager->tempFile; /* ticket fb3b3024ea238d5c */
   return rc;
 }
 
@@ -5365,6 +5373,7 @@ int sqlite3PagerSharedLock(Pager *pPager){
       assert( pPager->eState==PAGER_OPEN );
       assert( (pPager->eLock==SHARED_LOCK)
            || (pPager->exclusiveMode && pPager->eLock>SHARED_LOCK)
+           || (pPager->eMinLock>0 && pPager->eLock>=SHARED_LOCK)
       );
     }
 
@@ -6680,9 +6689,8 @@ commit_phase_one_exit:
 ** If an error occurs, an IO error code is returned and the pager
 ** moves into the error state. Otherwise, SQLITE_OK is returned.
 */
-int sqlite3PagerCommitPhaseTwo(Pager *pPager, int bKeepLocked){
+int sqlite3PagerCommitPhaseTwo(Pager *pPager){
   int rc = SQLITE_OK;                  /* Return code */
-  u8 modeSaved;
 
   /* This routine should not be called if a prior error has occurred.
   ** But if (due to a coding error elsewhere in the system) it does get
@@ -6717,10 +6725,7 @@ int sqlite3PagerCommitPhaseTwo(Pager *pPager, int bKeepLocked){
   }
 
   PAGERTRACE(("COMMIT %d\n", PAGERID(pPager)));
-  modeSaved = pPager->exclusiveMode;
-  pPager->exclusiveMode |= bKeepLocked;
   rc = pager_end_transaction(pPager, pPager->setSuper, 1);
-  pPager->exclusiveMode = modeSaved;
   return pager_error(pPager, rc);
 }
 
@@ -6891,6 +6896,24 @@ int sqlite3PagerIsMemdb(Pager *pPager){
   return pPager->tempFile || pPager->memVfs;
 }
 
+/*
+** Set the minimum locking level on all pagers.
+**
+**    0:  No minimum
+**    1:  Read lock
+**    2:  Write lock
+*/
+void sqlite3PagerMinLock(sqlite3 *db, u8 eMinLock){
+  int iDb;
+  Pager *pPager;
+  for(iDb=0; iDb<db->nDb; iDb++){
+    if( db->aDb[iDb].pBt==0 ) continue;
+    pPager = sqlite3BtreePager(db->aDb[iDb].pBt);
+    pPager->eMinLock = eMinLock;
+    if( pPager->pWal ) sqlite3WalMinLock(pPager->pWal, eMinLock);
+  }
+}
+
 /*
 ** Check that there are at least nSavepoint savepoints open. If there are
 ** currently less than nSavepoints open, then open one or more savepoints
index ddac6d17cdbd87c5e1e3e7507e81489ac194fcc3..1383367059100567e520a8140b572cdf7ee9e2d4 100644 (file)
@@ -165,7 +165,7 @@ int sqlite3PagerBegin(Pager*, int exFlag, int);
 int sqlite3PagerCommitPhaseOne(Pager*,const char *zSuper, int);
 int sqlite3PagerExclusiveLock(Pager*);
 int sqlite3PagerSync(Pager *pPager, const char *zSuper);
-int sqlite3PagerCommitPhaseTwo(Pager*,int);
+int sqlite3PagerCommitPhaseTwo(Pager*);
 int sqlite3PagerRollback(Pager*);
 int sqlite3PagerOpenSavepoint(Pager *pPager, int n);
 int sqlite3PagerSavepoint(Pager *pPager, int op, int iSavepoint);
@@ -218,6 +218,7 @@ void *sqlite3PagerTempSpace(Pager*);
 int sqlite3PagerIsMemdb(Pager*);
 void sqlite3PagerCacheStat(Pager *, int, int, u64*);
 void sqlite3PagerClearCache(Pager*);
+void sqlite3PagerMinLock(sqlite3*,u8);
 int sqlite3SectorSize(sqlite3_file *);
 
 /* Functions used to truncate the database file. */
index e5a0df289f3aefb3ea856b76a48b4e6d7fa23072..56c2cc911296a3013df2048ec541178e08ace0b8 100644 (file)
@@ -1649,7 +1649,6 @@ struct sqlite3 {
   u32 dbOptFlags;               /* Flags to enable/disable optimizations */
   u8 enc;                       /* Text encoding */
   u8 autoCommit;                /* The auto-commit flag. */
-  u8 autoRebegin;               /* Restart a new transaction on COMMIT */
   u8 temp_store;                /* 1: file 2: memory 0: default */
   u8 mallocFailed;              /* True if we have seen a malloc failure */
   u8 bBenignMalloc;             /* Do not require OOMs if true */
index 4e867b65701edb952c516f46299371fd605ca632..a9549aa7f5f8d215e89ce66f6c65d287a8299dd3 100644 (file)
@@ -148,7 +148,7 @@ static int SQLITE_TCLAPI pager_commit(
     Tcl_AppendResult(interp, sqlite3ErrName(rc), 0);
     return TCL_ERROR;
   }
-  rc = sqlite3PagerCommitPhaseTwo(pPager, 0);
+  rc = sqlite3PagerCommitPhaseTwo(pPager);
   if( rc!=SQLITE_OK ){
     Tcl_AppendResult(interp, sqlite3ErrName(rc), 0);
     return TCL_ERROR;
index 374fd9f0a01ab591d030addd8a62c8211c4d48b9..10783a8c3fb1a077ff56fb0be98d56a0b5e4aee9 100644 (file)
@@ -3978,9 +3978,9 @@ case OP_AutoCommit: {
     }else if( (rc = sqlite3VdbeCheckFk(p, 1))!=SQLITE_OK ){
       goto vdbe_return;
     }else{
-      db->autoRebegin = pOp->p3;
       db->autoCommit = (u8)desiredAutoCommit;
     }
+    sqlite3PagerMinLock(db, pOp->p3);
     if( sqlite3VdbeHalt(p)==SQLITE_BUSY ){
       p->pc = (int)(pOp - aOp);
       db->autoCommit = (u8)(1-desiredAutoCommit);
@@ -9144,6 +9144,7 @@ abort_due_to_error:
     rc = SQLITE_CORRUPT_BKPT;
   }
   assert( rc );
+  sqlite3PagerMinLock(db, 0);
 #ifdef SQLITE_DEBUG
   if( db->flags & SQLITE_VdbeTrace ){
     const char *zTrace = p->zSql;
index 9b16c1c5344b017ca81018c34f16139241c8379d..4414f7a2ec076a37f23c70e5f344b2c17c5788de 100644 (file)
@@ -2997,7 +2997,7 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){
     for(i=0; rc==SQLITE_OK && i<db->nDb; i++){
       Btree *pBt = db->aDb[i].pBt;
       if( pBt ){
-        rc = sqlite3BtreeCommitPhaseTwo(pBt, 0, db->autoRebegin!=0);
+        rc = sqlite3BtreeCommitPhaseTwo(pBt, 0);
       }
     }
     if( rc==SQLITE_OK ){
@@ -3141,7 +3141,7 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){
     for(i=0; i<db->nDb; i++){
       Btree *pBt = db->aDb[i].pBt;
       if( pBt ){
-        sqlite3BtreeCommitPhaseTwo(pBt, 1, db->autoRebegin!=0);
+        sqlite3BtreeCommitPhaseTwo(pBt, 1);
       }
     }
     sqlite3EndBenignMalloc();
index ea9bc4df884cf7ae74952f8320dea913866563da..f949073f4f38f8f700f264852b1b2b9293d2a8c6 100644 (file)
--- a/src/wal.c
+++ b/src/wal.c
@@ -516,6 +516,7 @@ struct Wal {
   i16 readLock;              /* Which read lock is being held.  -1 for none */
   u8 syncFlags;              /* Flags to use to sync header writes */
   u8 exclusiveMode;          /* Non-zero if connection is in exclusive mode */
+  u8 eMinLock;               /* 0, 1, or 2, for none, read, or write */
   u8 writeLock;              /* True if in a write transaction */
   u8 ckptLock;               /* True if holding a checkpoint lock */
   u8 readOnly;               /* WAL_RDWR, WAL_RDONLY, or WAL_SHM_RDONLY */
@@ -2064,7 +2065,7 @@ int sqlite3WalWriteLock(Wal *pWal, int bLock){
       }
       walDisableBlocking(pWal);
     }
-  }else if( pWal->writeLock ){
+  }else if( pWal->writeLock && pWal->eMinLock<2 ){
     walUnlockExclusive(pWal, WAL_WRITE_LOCK, 1);
     pWal->writeLock = 0;
   }
@@ -2698,7 +2699,7 @@ static int walIndexReadHdr(Wal *pWal, int *pChanged){
             *pChanged = 1;
           }
         }
-        if( bWriteLock==0 ){
+        if( bWriteLock==0 && pWal->eMinLock<2 ){
           pWal->writeLock = 0;
           walUnlockExclusive(pWal, WAL_WRITE_LOCK, 1);
         }
@@ -3670,7 +3671,7 @@ int sqlite3WalBeginWriteTransaction(Wal *pWal){
   /* Cannot start a write transaction without first holding a read
   ** transaction. */
   assert( pWal->readLock>=0 );
-  assert( pWal->writeLock==0 && pWal->iReCksum==0 );
+  // assert( pWal->writeLock==0 && pWal->iReCksum==0 );
 
   if( pWal->readOnly ){
     return SQLITE_READONLY;
@@ -3679,11 +3680,13 @@ int sqlite3WalBeginWriteTransaction(Wal *pWal){
   /* Only one writer allowed at a time.  Get the write lock.  Return
   ** SQLITE_BUSY if unable.
   */
-  rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1);
-  if( rc ){
-    return rc;
+  if( pWal->writeLock==0 ){
+    rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1);
+    if( rc ){
+      return rc;
+    }
+    pWal->writeLock = 1;
   }
-  pWal->writeLock = 1;
 
   /* If another connection has written to the database file since the
   ** time the read transaction on this connection was started, then
@@ -3708,7 +3711,7 @@ int sqlite3WalBeginWriteTransaction(Wal *pWal){
 ** routine merely releases the lock.
 */
 int sqlite3WalEndWriteTransaction(Wal *pWal){
-  if( pWal->writeLock ){
+  if( pWal->writeLock && pWal->eMinLock<2 ){
     walUnlockExclusive(pWal, WAL_WRITE_LOCK, 1);
     pWal->writeLock = 0;
     pWal->iReCksum = 0;
@@ -4419,7 +4422,7 @@ int sqlite3WalCallback(Wal *pWal){
 */
 int sqlite3WalExclusiveMode(Wal *pWal, int op){
   int rc;
-  assert( pWal->writeLock==0 );
+  // assert( pWal->writeLock==0 );
   assert( pWal->exclusiveMode!=WAL_HEAPMEMORY_MODE || op==-1 );
 
   /* pWal->readLock is usually set, but might be -1 if there was a
@@ -4456,6 +4459,13 @@ int sqlite3WalExclusiveMode(Wal *pWal, int op){
   return rc;
 }
 
+/*
+** Set the temporary minimum lock level for the WAL subsystem.
+*/
+void sqlite3WalMinLock(Wal *pWal, int eMinLock){
+  pWal->eMinLock = eMinLock;
+}
+
 /*
 ** Return true if the argument is non-NULL and the WAL module is using
 ** heap-memory for the wal-index. Otherwise, if the argument is NULL or the
index 1b17d2dfbe201c96cc98423ea1164bdf0bde396d..073a9529c4fb66c33f3f81615b8bebc7ede903da 100644 (file)
--- a/src/wal.h
+++ b/src/wal.h
@@ -129,6 +129,10 @@ int sqlite3WalExclusiveMode(Wal *pWal, int op);
 */
 int sqlite3WalHeapMemory(Wal *pWal);
 
+/* Set the transient minimum lock level for the WAL
+*/
+void sqlite3WalMinLock(Wal *pWal, int eMinLock);
+
 #ifdef SQLITE_ENABLE_SNAPSHOT
 int sqlite3WalSnapshotGet(Wal *pWal, sqlite3_snapshot **ppSnapshot);
 void sqlite3WalSnapshotOpen(Wal *pWal, sqlite3_snapshot *pSnapshot);