A method, implemented at least in part by a source node (200; 302; 535; 804; 1004; 1204) comprising a processing unit and memory, the source node being in communication with a replica node (220; 230; 304; 306; 540-550; 808; 1008; 1208), the source node storing at least one database table and the replica node storing a copy (226; 236) of the at least one database table, for replicating the at least one database table from the source node to the replica node, the method comprising: executing (905; 1308) a database operation on the at least one database table at the source node, wherein the database operation comprises a data manipulation statement modifying data; asynchronously sending (910; 1310) the database operation to the replica node, wherein the source node executes a subsequent operation without waiting for the database operation to be synchronized with the replica node; sending (925; 1316) a synchronous prepare commit request (850; 1250) to the replica node; receiving (930; 1318) a synchronous prepare commit acknowledgement (860; 1260) from the replica node, wherein the prepare commit acknowledgement indicates that the database operation was executed at the replica node; and committing (935; 1320) a transaction comprising the database operation at the source node; wherein the transaction comprises a query that reads a result of the database operation, the method further comprising, before committing the transaction: receiving (915; 1312), at the source node, the query from the replica node; and executing (920; 1314) the query at the source node; wherein the query is received if the database operation has not been executed by the replica node within a threshold time period; wherein, when the replica node receives the query, the replica node checks whether the query reads a result of the database operation, and delays execution of the query pending execution of the database operation; and if the database operation has been executed by the replica node within the threshold time period, the replica node executes the query after the database operation has been executed by the replica node. executing (905; 1308) a database operation on the at least one database table at the source node, wherein the database operation comprises a data manipulation statement modifying data; asynchronously sending (910; 1310) the database operation to the replica node, wherein the source node executes a subsequent operation without waiting for the database operation to be synchronized with the replica node; sending (925; 1316) a synchronous prepare commit request (850; 1250) to the replica node; receiving (930; 1318) a synchronous prepare commit acknowledgement (860; 1260) from the replica node, wherein the prepare commit acknowledgement indicates that the database operation was executed at the replica node; and committing (935; 1320) a transaction comprising the database operation at the source node; wherein the transaction comprises a query that reads a result of the database operation, the method further comprising, before committing the transaction: receiving (915; 1312), at the source node, the query from the replica node; and executing (920; 1314) the query at the source node; receiving (915; 1312), at the source node, the query from the replica node; and executing (920; 1314) the query at the source node; wherein the query is received if the database operation has not been executed by the replica node within a threshold time period; wherein, when the replica node receives the query, the replica node checks whether the query reads a result of the database operation, and delays execution of the query pending execution of the database operation; and if the database operation has been executed by the replica node within the threshold time period, the replica node executes the query after the database operation has been executed by the replica node.