IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Développement SQL Server Discussion :

Pourquoi ALTER DATABASE n'est pas autorisée dans une transaction multi-instruction ?


Sujet :

Développement SQL Server

  1. #1
    Membre à l'essai
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2013
    Messages
    24
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2013
    Messages : 24
    Points : 18
    Points
    18
    Par défaut Pourquoi ALTER DATABASE n'est pas autorisée dans une transaction multi-instruction ?
    Bonjour,

    J'ai le message :
    ALTER DATABASE n'est pas autorisée dans une transaction multi-instruction
    Côté java je définis une transaction qui exécute une procédure stockée de restore de base de données :
    Code java : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    DBTransaction     trans = (DBTransaction)appModule.getTransaction();
    CallableStatement callStmt = null;
     
    callStmt = trans.createCallableStatement( "EXEC MaProcédureStockéeRestore ?", DBTransaction.DEFAULT );
    callStmt.setString( 1, MonParamètre );
    callStmt.execute();

    Côté base de données :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    CREATE PROCEDURE MaProcédureStockéeRestore
    	@vSchema     VARCHAR(30)
    AS
    BEGIN
    	DECLARE  @sqlStatement		VARCHAR(512)
     
    	SELECT @sqlStatement = 'ALTER DATABASE ' + @vSchema  + ' SET SINGLE_USER WITH ROLLBACK IMMEDIATE'
    	EXECUTE( @sqlStatement )
     
    	SELECT @sqlStatement = 'RESTORE DATABASE + @vSchema + ' FROM DISK = ''C:\path\NomFichier.bak'''	
    	EXECUTE( @sqlStatement )
     
    	SELECT @sqlStatement = 'ALTER DATABASE [' + @vSchema  + '] SET MULTI_USER'
    	EXECUTE( @sqlStatement )
    END 
    GO
    Comment pourrais-je contourner ce problème ?

  2. #2
    Modérateur

    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Janvier 2005
    Messages
    5 826
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2005
    Messages : 5 826
    Points : 12 371
    Points
    12 371
    Par défaut
    Bonjour,

    Vous pouvez gérer cela avec le contrôle TRY ... CATCH.

    Il n'y a pas besoin d'une transaction.
    D'ailleurs, vous devriez gérer les transactions seulement sur le tiers données, ce qui raccourcira leur durée et donc augmentera la concurrence d'accès.

  3. #3
    Membre à l'essai
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2013
    Messages
    24
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2013
    Messages : 24
    Points : 18
    Points
    18
    Par défaut
    Elsuket,

    Pouvez-vous me donner un exemple ?
    Côté java, je suis obligé de passer par un transaction pour appeler ma procédure stockée.

  4. #4
    Membre à l'essai
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2013
    Messages
    24
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2013
    Messages : 24
    Points : 18
    Points
    18
    Par défaut
    J'ai réussi à contourner le problème en passant par SQLCMD

    Côté Java :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    DBTransaction     trans = (DBTransaction)appModule.getTransaction();
    CallableStatement callStmt = null;
     
    callStmt = trans.createCallableStatement( "EXEC MaProcédureStockéeRestore ?", DBTransaction.DEFAULT );
    callStmt.setString( 1, MonParamètre );
    callStmt.execute();
    Côté base de données :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    CREATE PROCEDURE MaProcédureStockéeRestore 
    AS
    BEGIN
    	DECLARE  @v_Command  VARCHAR(512)
    	SELECT @v_command = 'SqlCmd -i "C:\restore.sql"' 
     
    	EXEC master..XP_CMDSHELL  @v_Command
    END 
    GO
    C:\restore.sql :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    ALTER DATABASE MaBase SET SINGLE_USER WITH ROLLBACK IMMEDIATE
    GO
     
    DECLARE @fileName NVARCHAR(255)
    SET @fileName = N'C:\MonFichier.bak' 
     
    RESTORE DATABASE [MaBase]
    FROM DISK = @fileName
    GO
     
    ALTER DATABASE [MaBase] SET MULTI_USER
    GO

  5. #5
    Membre à l'essai
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2013
    Messages
    24
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2013
    Messages : 24
    Points : 18
    Points
    18
    Par défaut
    Avec la solution de contournement, la base de données se retrouve dans l'état "SUSPENDED" à l'instruction "
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    ALTER DATABASE MaBase SET SINGLE_USER WITH ROLLBACK IMMEDIATE
    Le type d'attente est à "PRINT_ROLLBACK_PROGRESS"

    J'ai vérifié dans sys.databases que la colonne AUTO_UPDATE_STATISTICS_ASYNC est bien à 0 (OFF)

    Du coup le RESTORE ne s'effectue pas.

    Pour information, dans MS SQL Server Management Studio quand j'appelle ma procédure, ça marche
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    EXEC MaProcédureStockéeRestore

  6. #6
    Membre à l'essai
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2013
    Messages
    24
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2013
    Messages : 24
    Points : 18
    Points
    18
    Par défaut
    Qui pourrait m'expliquer pourquoi, l'appel de ma procédure via java ne marche pas et reste en SUSPENDED ?
    Quelle(s) démarches suivre pour débloquer la situation ?
    Merci pour vos réponse .

  7. #7
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 772
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Expert bases de données / SQL / MS SQL Server / Postgresql
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 21 772
    Points : 52 735
    Points
    52 735
    Billets dans le blog
    5
    Par défaut
    Le scope transactionnel est, et restera, toujours limité à l'intérieur de la base, même s'il est possible de faire des transactions distribuées (qui peuvent se terminer mal de façon logique et difficilement récupérable). À me lire sur ce dernier sujet :
    http://blog.developpez.com/sqlpro/p1..._a_deux_phases

    Abandonnez votre idée de modifier l'enveloppe logique que constitue une base de données en essayant d'ajouter une super transaction de niveau serveur !

    Quel est le but fonctionnel ?

    A +
    Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
    Le site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
    Blog SQL, SQL Server, SGBDR : http://blog.developpez.com/sqlpro
    Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
    Entreprise SQL SPOT : modélisation, conseils, audit, optimisation, formation...
    * * * * * Expertise SQL Server : http://mssqlserver.fr/ * * * * *

  8. #8
    Membre à l'essai
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2013
    Messages
    24
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2013
    Messages : 24
    Points : 18
    Points
    18
    Par défaut
    Le but fonctionel est celui-ci :
    Le premier but est de pouvoir exporter des données d'une BD1 vers des fichiers en passant par une BD2 tampon.
    La BD1 contient les données.
    1 - La BD2 tampon est créée "vide" (presque car il y un minimum de données)
    2 - Sauvegarde de la BD2 tampon
    3 - On synchronise les données de la BD2 tampon avec la BD1
    4 - On décharge les données de la BD2 tampon dans des fichiers (via bcp) et restauration de la BD2 Tampon à "vide"

    Le deuxième but est de pouvoir importer des données contenues dans ces fichiers vers une BD3 toujours en passant par une BD2 tampon.
    1 - On charge les données des fichiers sur la BD2 tampon
    2 - On synchronise les données de la BD3 avec la BD2 tampon

    Les fichiers bcp permettront de configurer plusieurs BD à la fois et sur différents serveurs
    La BD2 tampon permet de ne pas toucher à la BD1 pour garantir la sécurité de données.

Discussions similaires

  1. la balise "h5" n'est pas autorisée dans "a"
    Par Mister Paul dans le forum Balisage (X)HTML et validation W3C
    Réponses: 17
    Dernier message: 16/01/2011, 19h02
  2. [XL-2003] RechercheV n'est pas exprimée dans une boucle
    Par comme de bien entendu dans le forum Excel
    Réponses: 2
    Dernier message: 05/05/2010, 10h37
  3. Réponses: 3
    Dernier message: 23/05/2009, 13h07
  4. [Smarty] Pourquoi le php n'est pas recommandé dans les templates ?
    Par SlymDesign dans le forum Bibliothèques et frameworks
    Réponses: 5
    Dernier message: 10/10/2007, 11h21
  5. Réponses: 26
    Dernier message: 05/02/2007, 16h57

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo