2009-12-17 4 views
0

J'ai une application Web qui traite les fichiers et écrit les données dans une base de données. Ce processus peut prendre jusqu'à 2 minutes. Disons que ceci est fait sur ProcessFile.aspx. Je voulais assurer l'intégrité des données, donc j'ai enveloppé tout le traitement de la base de données dans un TransactionScope.Problème lors de l'accès à une autre page alors que la première page traite un fichier

Le problème se produit lorsque je suis en train de traiter un fichier, puis essayez d'accéder à une autre page qui accède également à la base de données (il suffit de lire certaines données via une instruction select). Je suis à peu près sûr que cela n'a rien à voir avec le verrouillage de la base de données, car quand je passe directement par SQL Server Management Studio, je n'ai aucun problème à sélectionner sur une table.

J'utilise LinqToSQL. J'ai un ScriptManager sur la page maître. Toutes les pages héritent de cette page maître. ProcessFile.aspx a un UpdatePanel mais pas l'autre page.

Qu'est-ce qui me manque ici? Si plus d'informations sont nécessaires, commentez et je mettrai à jour la question.

EDIT 1: je reçois ce message d'exception

Type : System.Data.SqlClient.SqlException, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 
Message : Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding. 
Source : .Net SqlClient Data Provider 

J'ouvre la deuxième page dans une fenêtre de navigateur. Il continue tout simplement à se charger jusqu'à ce que la première page ait fini de traiter le fichier, puis se charge normalement.

Je ne fais pas un appel d'une page à l'autre. Il suffit d'ouvrir une autre page via une autre fenêtre du navigateur via la barre d'adresse.

EDIT 2: Ceci est la première fois que je suis venu à travers où plus d'une réponse résolu mon problème. Les réponses de Remus et de Rick en même temps l'ont résolu pour moi. Je ne savais pas qui choisir comme réponse correcte, alors j'ai retourné une pièce et Rick a gagné. Désolé, Remus! Je ne voulais pas le donner à personne. Cependant, j'avais besoin de mettre en œuvre les deux réponses pour que cela fonctionne.

Répondre

1

Utilisez-vous l'état de session? Si tel est le cas, les sessions par défaut utilisent un verrou exclusif, de sorte que vous ne pouvez émettre qu'une seule demande à la fois.

Vous pouvez contourner ce problème en désactivant l'état de session pour la page à exécution longue ou en marquant la page comme ayant uniquement besoin de sessions en mode lecture seule.

+0

Salut Rick. Par sessions, voulez-vous dire l'état de la session? – Andrew

+0

Oui, état de la session. – RickNZ

+0

Pour tous ceux qui ont le même problème que moi. S'il vous plaît, regardez aussi la réponse de Remus car c'était aussi nécessaire pour la résoudre. – Andrew

0

Quel problème avez-vous exactement - timeout? exception?
Que voulez-vous dire accéder à une autre page?
- Dans la même fenêtre du navigateur?
- Une autre fenêtre séparée?
- Vous appelez d'une page à une autre?

1

Il s'agit probablement du verrouillage de la base de données.

Par défaut, le TransactionScope utilise un niveau d'isolation de transaction sérialisable, ce qui signifie que la première page placera des verrous de plage sur tout ce qu'il lit. La deuxième page va essayer de faire des opérations sur ces plages verrouillées et sera en conflit. Votre SSMS select from table ne prouve pas grand-chose, nous savons déjà que les verrous partagés ne sont pas en conflit.

Ouvrir la première page. Ensuite, ouvrez votre deuxième page et en attendant, vérifiez la liste de blocage dans le activity monitor. Vous trouverez les demandes de la deuxième page bloquées derrière les verrous détenus par la première page. La ressource de contention doit indiquer exactement quelle opération le blocage se produit.

La solution la plus simple consiste à utiliser le niveau d'isolement ReadCommited dans TransactionScope et à activer read commited snapshot dans la base de données.

+0

Merci pour la réponse. J'ai imbriqué TransactionScopes. Est-ce que chacun d'entre eux doit également être configuré pour avoir un niveau d'isolation ReadCommitted? Je pense oui? – Andrew

+0

AFAIK pas. La portée la plus externe doit avoir un niveau d'isolation explicite, mais les étendues internes hériteront du TransactioOptions IsolationLevel de la portée externe. Si la portée interne spécifie un niveau d'isolation qui n'est pas le même que celui de la portée externe, elle lèvera une exception, il vaut donc mieux ne prendre en compte que speicfy dans la portée la plus extérieure, si possible. –

+0

Cela a fonctionné pour moi en conjonction avec la réponse de RickNZ. – Andrew

Questions connexes