@@ -812,7 +812,8 @@ public function begin_transaction(): void {
812812 */
813813 $ this ->execute_sqlite_query ( $ this ->is_readonly ? 'BEGIN ' : 'BEGIN IMMEDIATE ' );
814814 } else {
815- $ this ->execute_sqlite_query ( 'SAVEPOINT LEVEL ' . $ this ->transaction_level );
815+ $ savepoint_name = $ this ->get_internal_savepoint_name ( $ this ->transaction_level );
816+ $ this ->execute_sqlite_query ( sprintf ( 'SAVEPOINT %s ' , $ savepoint_name ) );
816817 }
817818 ++$ this ->transaction_level ;
818819 }
@@ -829,7 +830,8 @@ public function commit(): void {
829830 if ( 0 === $ this ->transaction_level ) {
830831 $ this ->execute_sqlite_query ( 'COMMIT ' );
831832 } else {
832- $ this ->execute_sqlite_query ( 'RELEASE SAVEPOINT LEVEL ' . $ this ->transaction_level );
833+ $ savepoint_name = $ this ->get_internal_savepoint_name ( $ this ->transaction_level );
834+ $ this ->execute_sqlite_query ( sprintf ( 'RELEASE SAVEPOINT %s ' , $ savepoint_name ) );
833835 }
834836 }
835837
@@ -845,7 +847,8 @@ public function rollback(): void {
845847 if ( 0 === $ this ->transaction_level ) {
846848 $ this ->execute_sqlite_query ( 'ROLLBACK ' );
847849 } else {
848- $ this ->execute_sqlite_query ( 'ROLLBACK TO SAVEPOINT LEVEL ' . $ this ->transaction_level );
850+ $ savepoint_name = $ this ->get_internal_savepoint_name ( $ this ->transaction_level );
851+ $ this ->execute_sqlite_query ( sprintf ( 'ROLLBACK TO SAVEPOINT %s ' , $ savepoint_name ) );
849852 }
850853 }
851854
@@ -4109,6 +4112,19 @@ private function get_sqlite_index_name( string $mysql_table_name, string $mysql_
41094112 return $ mysql_table_name . '__ ' . $ mysql_index_name ;
41104113 }
41114114
4115+ /**
4116+ * Get an internal savepoint name.
4117+ *
4118+ * Internal savepoints are used to emulate MySQL transactions that are run
4119+ * inside a wrapping SQLite transaction, as transactions can't be nested.
4120+ *
4121+ * @param int $level The transaction nesting level.
4122+ * @return string The internal savepoint name.
4123+ */
4124+ private function get_internal_savepoint_name ( int $ level ): string {
4125+ return sprintf ( '%ssavepoint_%d ' , self ::RESERVED_PREFIX , $ level );
4126+ }
4127+
41124128 /**
41134129 * Get an SQLite query to emulate MySQL "ON UPDATE CURRENT_TIMESTAMP".
41144130 *
0 commit comments