Descubrió que OleDBConnection no parece ser ThreadSafe. Parece que intenta abrir conexiones múltiples en su lugar.ExecuteNonQuery en paralelo dentro de una OleDbConnection/OleDbTransaction compartida
//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();
}
});
Si bloqueo la conexión para un ExecuteNonQuery los errores desaparecen, pero los tanques de rendimiento.
//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();
}
}
});
Supongamos que
que no puedo cambiar la naturaleza de la ORM: el SQL no puede ser abultado
Las reglas de negocio requieren que la interacción se lleva a cabo en una sola transacción
Así:
¿Existe alguna forma mejor o más eficaz para paralelizar las interacciones OleDb?
En caso negativo, ¿existe alguna alternativa al cliente OleDb que pueda aprovechar al máximo el paralelismo? (Tal vez el cliente MSSQL nativa?)
Mucha información excelente aquí. Para su punto de medición, me temo que lo que termino es de manzanas a naranjas: puedo comparar 1 conexión y 1 transacción ejecutándose en serie a 80,000 conexiones y transacciones en paralelo (con agrupación). Entre ellos, hay una diferencia de 15 segundos (aproximadamente un minuto y medio en total). Dependiendo de cuán eficientemente funcione la agrupación, esperaba un ahorro sustancial si pudiera mantener la misma conexión. – seraphym
Adición: El escenario anterior con 1 conexión + bloqueo sale a unos 10 segundos más rápido que el serial, y unos 5 segundos más lento que el 'paralelo completo' – seraphym