web-dev-qa-db-fra.com

Combien de temps SET READ_COMMITTED_SNAPSHOT ON doit-il durer?

Combien de temps faut-il pour courir 

ALTER DATABASE [MySite] SET READ_COMMITTED_SNAPSHOT ON

Je viens de le lancer et cela a pris 10 minutes.

Comment puis-je vérifier s'il est appliqué?

65
Simon_Weaver

Vous pouvez vérifier l'état du paramètre READ_COMMITTED_SNAPSHOT à l'aide de la vue sys.databases. Vérifiez la valeur de la colonne is_read_committed_snapshot_on. Déjà demandé et répondu .

En ce qui concerne la durée, la documentation en ligne indique qu'il ne peut y avoir aucune autre connexion à la base de données lorsque cela se produit, mais cela ne nécessite pas le mode utilisateur unique. Donc, vous pouvez être bloqué par d'autres connexions actives. Exécutez sp_who (ou sp_who2) pour voir ce qui est connecté à cette base de données.

63
Rick

Essaye ça:

ALTER DATABASE generic SET READ_COMMITTED_SNAPSHOT ON WITH ROLLBACK IMMEDIATE
40
faheem

OK (je suis le questionneur d'origine), donc il s'avère que pendant tout ce temps, je n'avais même pas activé la fichue chose.

Voici le code ultime à exécuter pour activer le mode Instantané et vous assurer qu'il est activé. 

SELECT is_read_committed_snapshot_on, snapshot_isolation_state_desc,snapshot_isolation_state FROM sys.databases WHERE name='shipperdb'

ALTER DATABASE shipperdb SET allow_snapshot_isolation ON
ALTER DATABASE shipperdb SET SINGLE_USER WITH ROLLBACK IMMEDIATE
ALTER DATABASE shipperdb SET read_committed_snapshot ON
ALTER DATABASE shipperdb SET MULTI_USER

SELECT is_read_committed_snapshot_on, snapshot_isolation_state_desc,snapshot_isolation_state FROM sys.databases WHERE name='shipperdb'

Cela fonctionne même avec des connexions actives (vraisemblablement, vous vous en sortiriez bien.).

Vous pouvez voir l'état avant et après et cela devrait fonctionner presque immédiatement.


IMPORTANT: 

L'option READ_COMMITTED_SNAPSHOT ci-dessus correspond à IsolationLevel.ReadCommitted dans .NET
L’option ALLOW_SNAPSHOT_ISOLATION ci-dessus correspond à IsolationLevel.Snapshot dans .NET

_ { Excellent article sur les versions différentes


Astuces .NET:

On dirait que Isolationlevel.ReadCommitted est autorisé dans le code même s'il n'est pas activé par la base de données. Aucun avertissement n'est lancé. Alors faites-vous plaisir et assurez-vous qu'il est allumé avant de supposer que c'est pour 3 ans comme je l'ai fait !!!

Si vous utilisez C #, vous voulez probablement le ReadCommitted IsolationLevel et non le Snapshot - à moins que vous ne fassiez des écritures dans cette transaction.

READ COMMITTED SNAPSHOT fait des lectures optimistes et des écritures pessimistes. En revanche, SNAPSHOT fait des lectures optimistes et des écritures optimistes. (d'ici)

bool snapshotEnabled = true;

using (var t = new TransactionScope(TransactionScopeOption.Required,
               new TransactionOptions
{
     IsolationLevel = IsolationLevel.ReadCommitted
}))
{
     using (var shipDB = new ShipperDBDataContext())
     {

     }
}

De plus, vous pouvez obtenir une erreur indiquant qu’il est «impossible de promouvoir» une transaction. Recherchez "promotion" dans Présentation de System.Transactions dans le .NET Framework 2.0 .

À moins que vous ne fassiez quelque chose de spécial, comme une connexion à une base de données externe (ou une deuxième base de données), quelque chose d'aussi simple que de créer un nouveau DataContext peut provoquer cela. J'avais un cache qui "créait" son propre contexte de données lors de l'initialisation, ce qui tentait de faire passer la transaction à une version distribuée complète.

La solution était simple:

        using (var tran = new TransactionScope(TransactionScopeOption.Suppress))
        {
            using (var shipDB = new ShipperDBDataContext())
            { 
                 // initialize cache
            }
        }

Voir aussi Deadlocked article de @CodingHorror

25
Simon_Weaver

Essayez ce code:

if(charindex('Microsoft SQL Server 2005',@@version) > 0)
begin
    declare @sql varchar(8000)
    select @sql = '
    ALTER DATABASE ' + DB_NAME() + ' SET SINGLE_USER WITH ROLLBACK IMMEDIATE ;
    ALTER DATABASE ' + DB_NAME() + ' SET READ_COMMITTED_SNAPSHOT ON;
    ALTER DATABASE ' + DB_NAME() + ' SET MULTI_USER;'

    Exec(@sql)
end
8
Nick Berardi

Je n'ai pas pris une seconde pour moi quand j'ai changé ma base de données en utilisateur unique

2
Yasin Kilicdere

Essayez d'utiliser la base de données master avant de modifier la base de données actuelle.

USE Master
GO

ALTER DATABASE [YourDatabase] SET READ_COMMITTED_SNAPSHOT ON
GO
2
eLVik

J'ai essayé la commande:

ALTER DATABASE MyDB SET READ_COMMITTED_SNAPSHOT ON
GO

contre une boîte de dev mais cela a pris plus de 10 minutes et donc je l’ai tué. 

J'ai alors trouvé ceci: 

https://willwarren.com/2015/10/12/sql-server-read-committed-snapshot/

et a utilisé son bloc de code (qui a pris environ 1:26):

USE master
GO

/** 
 * Cut off live connections
 * This will roll back any open transactions after 30 seconds and
 * restricts access to the DB to logins with sysadmin, dbcreator or
 * db_owner roles
 */
ALTER DATABASE MyDB SET RESTRICTED_USER WITH ROLLBACK AFTER 30 SECONDS
GO

-- Enable RCSI for MyDB
ALTER DATABASE MyDB SET READ_COMMITTED_SNAPSHOT ON
GO

-- Allow connections to be established once again
ALTER DATABASE MyDB SET MULTI_USER
GO

-- Check the status afterwards to make sure it worked
SELECT is_read_committed_snapshot_on
FROM sys.databases
WHERE [name] = 'MyDB '
2
Jeff Mergler

Essayez de fermer les autres services SQL afin que seul le service serveur SQL soit en cours d'exécution. 

Le mien a fonctionné pendant 5 minutes puis je l'ai annulé car il était évident que rien ne se passait. C'est un tout nouveau serveur, il n'y a donc pas d'autres utilisateurs connectés. J'ai arrêté SQL Reporting Services, puis je l'ai réexécuté. Il m'a fallu moins d'une seconde pour terminer. 

0
Jeff