
Forcing a Mark to Spread to Other Servers
A transaction mark name is not automatically distributed to another server as the transaction spreads there. To force the mark to spread to the other servers, a stored procedure must be written that contains a BEGIN TRAN name WITH MARK statement. That stored procedure must then be executed on the remote server under the scope of the transaction in the originating server.
For example, consider a partitioned database that exists on multiple instances of SQL Server. On each instance is a database named coyote. First, in every database, create a stored procedure, for example, sp_SetMark.
CREATE PROCEDURE sp_SetMark
@name nvarchar (128)
AS
BEGIN TRANSACTION @name WITH MARK
UPDATE coyote.dbo.Marks SET one = 1
COMMIT TRANSACTION;
GO
Next, create stored procedure sp_MarkAll containing a transaction that places a mark in every database. sp_MarkAll can be run from any of the instances.
CREATE PROCEDURE sp_MarkAll
@name nvarchar (128)
AS
BEGIN TRANSACTION
EXEC instance0.coyote.dbo.sp_SetMark @name
EXEC instance1.coyote.dbo.sp_SetMark @name
EXEC instance2.coyote.dbo.sp_SetMark @name
COMMIT TRANSACTION;
GO
Two-Phase Commit
Committing a distributed transaction occurs in two phases: prepare and commit. When a marked transaction is committed, the commit log record for each database in the marked transaction is placed in the log at a point where there are no in-doubt transactions in any of the logs. At this point, it is guaranteed that there are no transactions that appear as committed in one log, but not committed in another log.
The following steps accomplish this during the commit of a marked transaction:
-
Prepare phase of a marking transaction stalls all new prepares and commits.
-
Only commits of already prepared transactions are allowed to continue.
-
Marking transaction then waits for all prepared transactions to drain (with time-out).
-
Marked transaction is prepared and committed.
-
The stall of new prepares and commits is removed.
The stalls generated by marked transactions that span multiple databases can reduce the transaction processing performance of the server.
We recommend that you do not run concurrent marked transactions. It is rare but possible for the commit of a distributed marked transaction to deadlock with other distributed marked transactions that are committing at the same time. When this happens, the marking transaction is chosen as the deadlock victim and is rolled back. When this error occurs, the application can retry the marked transaction. When multiple marked transactions try to commit concurrently, there is a higher probability of deadlock.