web-dev-qa-db-fra.com

transaction sur plusieurs bases de données - Quelle est la surcharge?

J'exécute la mise à jour suivante, qui est une seule transaction sur 2 bases de données.

Veuillez noter que je n'ai pas commis la transaction.

--================================================================
--RUN THE UPDATE
--================================================================

BEGIN TRANSACTION T1_radhe

SET TRANSACTION ISOLATION LEVEL REPEATABLE READ

SELECT @@TRANCOUNT

BEGIN TRY

UPDATE DEStock.DBO.ItemStock 
SET     QtyOnOrder = 0 ,
        DueDate = NULL
FROM DEStock.DBO.ItemStock T
INNER JOIN TABLEBACKUPS.DBO.__RADHE R
        ON T.ITEMNO = R.ITEMNO

print cast ( @@rowcount  as varchar) + ' updating DEStock.DBO.ItemStock '


UPDATE USStock.DBO.ItemStock 
SET     QtyOnOrder = 0 ,
        DueDate = NULL
FROM USStock.DBO.ItemStock T
INNER JOIN TABLEBACKUPS.DBO.__RADHE R
        ON T.ITEMNO = R.ITEMNO

print cast ( @@rowcount  as varchar) + ' updating USStock.DBO.ItemStock '



--COMMIT TRANSACTION T1

END TRY
BEGIN CATCH

    DECLARE @ErrorMessage NVARCHAR(4000);
    DECLARE @ErrorSeverity INT;
    DECLARE @ErrorState INT;

    WHILE @@TRANCOUNT > 0
         ROLLBACK TRANSACTION

    SELECT 
        @ErrorMessage = ERROR_MESSAGE(),
        @ErrorSeverity = ERROR_SEVERITY(),
        @ErrorState = ERROR_STATE();

    RAISERROR (@ErrorMessage, -- Message text.
               @ErrorSeverity, -- Severity.
               @ErrorState -- State.
               );
END CATCH

Je reçois le résultat suivant de la mise à jour ci-dessus:

(196 rangées affectées (s)) 196 Mise à jour dutock.dbo.ItemStock

(196 Rangée (s) affectée (s)) 196 Mise à jour de USStock.dbo.ItemStock

Mais lorsque je regarde les journaux de transaction des bases de données en question, j'ai la même vue sur leurs journaux:

enter image description here

enter image description here

La SPID dans chaque base de données est la même, 6434, mais le transaction_id semble être différent dans chaque base de données.

Comment ça va?

De plus, lors de l'exécution du script suivant après avoir effectué la restauration sur les Updotes ci-dessus, j'avais toujours les mêmes résultats qu'avant la restauration.

Je devais ajouter l'option recompiler afin que je puisse voir que la transaction n'était plus là.

use DEStock
go
select db_name(),@@trancount
go
Select SPID, [Master DBID], [Master XDESID], Operation, Context, [Transaction ID]
FROM sys.fn_dblog(NULL,NULL) where  [Transaction Name] = 'T1_radhe'
option (recompile)

Quelle est la surcharge d'avoir des transactions sur plusieurs bases de données? Je travaille avec cela assez souvent parce que j'ai beaucoup de marchés; Chaque marché a un ensemble de bases de données.

Existe-t-il un moyen de faire fonctionner ces transactions plus rapidement? Je pensais à des transactions distribuées.

La table utilisée sur le joint vient d'ici: Comment insérer une liste de valeurs de Varchark, dans une seule table de colonnes?

Ce lien explique la fonction FN_DBLOG: SQL Server Fn_DBlog () Détails de la fonction et exemple

4
Marcello Miorelli

la SPID dans chaque base de données est la même, 6434, mais le transaction_id semble être différent dans chaque base de données.

comment ça va?

Ce que vous avez mal est faux (peut-être que vous regardez une plus ancienne transaction qui a le même nom de nom).

De mon test, je peux voir que les ID de transaction correspondent (voir ci-dessous)

enter image description here

En utilisant sp_WhoIsActive avec @get_transaction_info = 1, Je reçois en dessous des détails de transaction

test_HV: 15 (1 kB),tempdb: 0 (0 kB),AdventureWorks_2005: 0 (0 kB)

Vous pouvez facilement Vérifiez si la base de données fait partie de la transaction croisée de la base de données

-- check if database is involved in Cross database transactions
if exists (
        select *
        from fn_dblog(null, null)
        where Operation = 'LOP_PREP_XACT'
            and [Master DBID] <> 0
        )
    print 'Based on the active part of the transaction log read, there is evidence that this database has participated in cross-database transactions.'
else
    print 'Based on the active part of the transaction log read, there is no evidence of this database having participated in cross-database transactions.'

---- check for Distributed Transaction Coordinator involvement (below)
if exists (
        select *
        from fn_dblog(null, null)
        where Operation = 'LOP_PREP_XACT'
            and [Master DBID] = 0
        )
    print 'Based on the active part of the transaction log read, there is evidence that this database has participated in distributed transactions.'
else
    print 'Based on the active part of the transaction log read, there is no evidence of this database having participated in distributed transactions.'

quelle est la surcharge d'avoir des transactions sur plusieurs bases de données?

Une transaction elle-même n'a pas de coût associé (ou d'être plus spécifique, elle est très très négligeable) de citation de ma réponse :

Des transactions sont nécessaires pour prendre la base de données d'un état cohérent dans un autre État cohérent. Les transactions n'ont aucun coût car il n'y a pas d'alternative aux transactions.

Toute modification de la base de données générera des enregistrements de journal, utiliser la mémoire et la CPU avec l'espace TEMPDB (dépend de si vous effectuez une grande sorte, puis mettez à jour ou supprimez des enregistrements, puis les déversements à TEMPDB seront vus ou si vous utilisez le niveau d'isolation de l'instantané, etc).

existe-t-il un moyen de faire fonctionner ces transactions plus rapidement?

Oui, faites votre mises à jour en lots ou morceaux . Tout d'abord, sélectionnez et mettez à jour uniquement ces lots et assurez-vous d'avoir des index appropriés sur les tables impliquées, de sorte que SQL Server recherchera simplement les lignes et les mettre à jour.

Je pensais à des transactions distribuées.

Je voudrais éviter Les transactions distribuées car elles ne sont pas prises en charge dans la mise en miroir de la base de données ou toujours ( SQL Server 2016 a une prise en charge limitée ) et si vous êtes Lucky = - Vous obtiendrez une spid de transaction DTC orpheld .

Comme une note latérale,

  • Sauf si vous utilisez sys.fn_dblog Pour des fins éducatives ou sur des environnements non prod, vous devriez être bon. Je voudrais éviter d'utiliser dans des environnements de produit!
  • Vous utilisez SET TRANSACTION ISOLATION LEVEL REPEATABLE READ. Cela signifie que vous aurez lignes de fantôme (ce qui peut conduire à des résultats inattendus) - Donc, en vous assurant que vous soyez conscient de ce que vous utilisez.

Contrairement à une analyse commise en lecture, une analyse de lecture répétable conserve des serrures sur chaque rangée qu'il touche jusqu'à la fin de la transaction. Même les lignes qui ne sont pas admissibles au résultat de la requête restent verrouillées. Ces serrures garantissent que les lignes touchées par la requête ne peuvent pas être mises à jour ou supprimées par une session simultanée tant que la transaction en cours se termine (qu'elle soit commise ou roulée). Ces verrous ne protègent pas les lignes qui n'ont pas encore été numérisées de mises à jour ou de suppression et n'empêchent pas l'insertion de nouvelles lignes au milieu des rangées déjà verrouillées.

3
Kin Shah