Rilevato che OleDBConnection non sembra essere ThreadSafe. Sembra che tenti di aprire più connessioni.ExecuteNonQuery in parallelo all'interno di un oggetto OleDbConnection/OleDbTransaction condiviso
//doesn't work
using (OleDbConnection oConn = TheDataAccessLayer.GetConnection())
using (OleDbTransaction oTran = oConn.BeginTransaction())
Parallel.ForEach(ORMObjects, (ORMObject, State) =>
{
if (!State.ShouldExitCurrentIteration && !State.IsExceptional)
{
var Error = ORMObject.SomethingThatExecutesANonQuery(oConn,oTran)
if (Error.Number != 0)
State.Stop();
}
});
Se blocco la connessione per un ExecuteNonQuery gli errori vanno via, ma i serbatoi di prestazioni.
//works
using (OleDbConnection oConn = TheDataAccessLayer.GetConnection())
using (OleDbTransaction oTran = oConn.BeginTransaction())
Parallel.ForEach(ORMObjects, (ORMObject, State) =>
{
if (!State.ShouldExitCurrentIteration && !State.IsExceptional)
{
lock(oConn)
{
var Error = ORMObject.SomethingThatExecutesANonQuery(oConn,oTran)
if (Error.Number != 0)
State.Stop();
}
}
});
Si supponga che
Non posso cambiare la natura della ORM: lo SQL non può essere gonfiato
regole aziendali richiedono che l'interazione essere eseguita all'interno di una singola transazione
Quindi:
Esiste un modo migliore/più efficiente per parallelizzare le interazioni OleDb?
In caso contrario, esiste un'alternativa al client OleDb che può sfruttare appieno il parallelismo? (Forse il cliente MSSQL nativo?)
Un sacco di ottime informazioni qui. Per quanto riguarda il tuo punto di misura, ciò che finisco è, temo, mele alle arance: posso confrontare 1 connessione e 1 transazione eseguendo in serie fino a 80.000 connessioni e transazioni in parallelo (w/pooling). Tra questi, c'è una differenza di 15 secondi (circa un minuto e mezzo del tutto). A seconda di come funziona efficientemente il pooling, speravo in risparmi sostanziali se potessi mantenere la stessa connessione. – seraphym
Addendum: Lo scenario di cui sopra con 1 collegamento + blocco esce per circa 10 secondi più veloce di serie e circa 5 secondi più lento di 'full parallela' – seraphym