Pregunta

Mientras uso ADO.NET (tal vez me equivoque, no sé cómo se llama) me doy cuenta de que solo puedo iniciar una transacción con una conexión y un comando parece tener comando. Transacción que me da los datos de la transacción pero no iniciar una transacción en sí? En realidad, mientras miro, veo esto en System.Data.SQLite

// Summary:
    //     The transaction associated with this command. SQLite only supports one transaction
    //     per connection, so this property forwards to the command's underlying connection.
    [Browsable(false)]
    [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
    public SQLiteTransaction Transaction { get; set; }

¿Entonces SQLite solo admite un período de transacción? Intenté abrir otra conexión, pero luego mi transacción arrojó una excepción sobre el bloqueo de la base de datos. Entonces, ¿no puedo tener más de una conexión concurrente también?

¿Fue útil?

Solución

Una transacción por conexión, sí, pero puede tener más de una conexión (cada una con su propia transacción activa).

Actualización: interesante. No sabía sobre el modo de caché compartida. Si su conexión está usando ese modo, solo una transacción está disponible para todas las conexiones que usan el mismo caché compartido. Consulte modo de caché compartida SQLite .

Otros consejos

No estoy seguro de las conexiones múltiples, probablemente tenga que ver con el hecho de que una conexión bloquea el archivo, ya que SQLite es una base de datos basada en archivos y no una base de datos basada en servidor (en una base de datos basada en servidor, el servidor mantiene todos los archivos bloqueados y se ocupa de las conexiones simultáneas).

Solo puede tener una transacción ABIERTA a la vez. Esto debería tener un sentido intuitivo, ya que todo lo que sucede después de comenzar una transacción está en esa transacción, hasta que un rollback o commit . Entonces puedes empezar uno nuevo. SQLite requiere que todos los comandos estén en una transacción, por lo que si no abre manualmente uno nuevo, lo hará por usted.

Si le preocupan las transacciones anidadas, puede falsificarlas con savepoint . Documentation

Dentro de 1 transacción, solo puede leer / escribir en 1 conexión hasta que se realice la transacción. Por lo tanto, debe pasar el objeto de conexión si realiza una transacción comercial que abarca varias declaraciones de SQL como esta:

public class TimeTableService
    {
        ITimeTableDataProvider _provider = new TimeTableDataProvider();

        public void CreateLessonPlanner(WizardData wizardData)
        {
            using (var con = _provider.GetConnection())
            using (var trans = new TransactionScope())
            {
                con.Open();

                var weekListA = new List<Week>();
                var weekListB = new List<Week>();

                LessonPlannerCreator.CreateLessonPlanner(weekListA, weekListB, wizardData);

                _provider.DeleteLessonPlanner(wizardData.StartDate, con);

                _provider.CreateLessonPlanner(weekListA, con);
                _provider.CreateLessonPlanner(weekListB, con);

                _provider.DeleteTimeTable(TimeTable.WeekType.A, con);
                _provider.StoreTimeTable(wizardData.LessonsWeekA.ToList<TimeTable>(), TimeTable.WeekType.A, con);

                _provider.DeleteTimeTable(TimeTable.WeekType.B, con);
                _provider.StoreTimeTable(wizardData.LessonsWeekB.ToList<TimeTable>(), TimeTable.WeekType.B, con);

                trans.Complete();
            }
        }
    }

La declaración de uso libera / cierra automáticamente los recursos de conexión y transactividad.

En cada método de proveedor de datos que hagas

using(var cmd = new SQLiteCommand("MyStatement",con)
{
   // Create params + ExecuteNonQuery
}

La clase TransactionScope es nueva en .NET 3.5 y realiza una reversión automática si se produce una excepción. Fácil manejo ...

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top