| LUCIANO AGRIMONTI |
Cursori multipli
Ho un quesito da porvi in merito alla gestione degli accessi alle tabelle utilizzando i DataReader.
Dovendo migrare un'applicazione Mainframe (CICS/DB2) su ASP.NET, ho letto che Microsoft consiglia l'uso dei DataReader per ottenere le performance migliori ed avere un'apprezzabile scalabilità. Il DataReader tiene però occupata la connessione in modo esclusivo non permettendo quindi nessun'altra operazione di I/O (Select, Update o altro 'cursore' (DataReader) di lettura). Una funzione dell'applicazione ha la necessità di utilizzare più cursori identati contemporaneamente: apro un cursore (DataReader) e per ogni riga in esso presente effettuo altre operazioni come la lettura di una riga da un'altra tabella oppure la ricerca di altri dati tramite un altro cursore. Su DB2 posso aprire un numero di cursori indefinito, fare accesso diretto a qualsiasi tabella e fare qualsiasi operazione di aggiornamento: inserire, variare, cancellare e addirittura fare cursori per aggiornamento. E tutto questo nell'ambito della stessa unità di elaborazione e quindi assoggettabile ad un unico Syncpoint o Rollback per tutte le operazioni di aggiornamento. Ebbene, come afferma la documentazione (in modo molto preciso), non posso effettuare altre select o generare altri DataReader fino a quando non ho chiuso quello in uso attualmente per la connessione corrente. Per risolvere il problema ho pensato: definisco ed utilizzo più connessioni. Con una gestisco il cursore principale e con le altre accedo a quello che voglio eccetera. Però mi viene il dubbio che se mi trovo nella necessità di eseguire un Rollback diventa un poco dispendiosa la sua gestione. Forse con i DataSet si risolve tutto ma vorrei comprendere se esiste un metodo alternativo. Poi ho pensato: ma vuoi che il framework non abbia qualcosa di più semplice o quantomeno di più funzionale?! Mi scuso ancora per la lunghezza ma mi sembra un argomento abbastanza importante ed interessante. Saluti, Luciano. |
| Carlo Pinasco |
Re: Cursori multipli
IL fatto è che in ADO.NET non esiste il supporto per i cursori lato server. In un mondo disconnesso quale quello attuale è importante non tenere aperte le connessioni verso i DB e l'utilizzo dei cursori deve essere evitato. I Datareader sono il modo più efficiente per estrarre dati da un DB e sono stati progettati per questo scopo, non per supportare cursori.
Non conosco il tuo problema, ma nel tuo caso userei i dataset, popolandoli con i record interessati. Una volta popolato il dataset farei tutte le modifiche del caso (sei disconnesso dal server), per poi inviare gli aggiornamenti (usando il metodo update). Il problema è quanti record sono coinvolti e/o se puoi operare in modalità disconnessa. Con ADODB, puoi operare con i cursori lato server, ma prima di usare un cursore ci penserei un milione di volte. La mia esperienza mi dice che nel 99% dei casi l'utilizzo dei cursori può essere evitato. Qui trovi alcuni articoli su MSDN che possono aiutarti: http://msdn.microsoft.com/msdnmag/issues/02/01/basics/basics0201.asp No Cursors in ADO.NET There is no cursor support in ADO.NET. Cursors are a database-specific technology and thus are tied to features of a particular database such as SQL Serverâ„¢ or Oracle. Cursors are also resource-intensive. The resources used depend on what type of cursor you select and where the cursor resides (client or server) and, of course, on the amount of data the cursor handles, the performance of the servers, and so on. Cursors are handy, but can really cause performance problems in applications. Early on, the ADO.NET team decided that performance would be a major consideration throughout the design of ADO.NET. Also important was default performance, also known as performance out of the box. As a result, ADO.NET does not support cursors. If your application absolutely needs cursor support, then you can use a previous version of ADO. Just be aware that your applications will not perform optimally because you'll be using COM Interop to access ADO from your .NET application. (This is in addition to the performance hit caused by the cursors.) I personally don't see the loss of cursors as a huge problem since Developers rarely resort to cursors. A good alternative is to just refresh the ADO.NET data upon demand. If you are using a DataSet, you can use the Merge method to pull in changes to the underlying data and merge them with the data in an existing table. For extremely high-performance read-only access, you can use the DataReader, which will allow you to pull data in a stream (like a fire-hose cursor) and manipulate it. In this case, there is no data to refresh. Just grab what you need and use it. Data Providers To connect to a data source in the .NET Framework you have a choice of two providers. The SQL Server .NET Data Provider is implemented in the SQLClient namespace. The OLE DB provider is in the OLE DB namespace and can be used to connect to many different databases, including Microsoft® Access and Oracle. http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vsent7/html/dvconChoosingRightDataAccessTechnology.asp http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vbcon/html/vbconADOPreviousVersionsOfADO.asp |