2011-04-27 8 views
13

Ayer estaba trabajando con algunas cosas de sqlalchemy que necesitaban un concepto de "selección ... para actualizar" para evitar una condición de carrera. La adición de .with_lockmode('update') a la consulta funciona un convite en InnoDB y PostgreSQL, SQLite, pero para que al final tener que colarse en uncómo hacer que sqlite seleccione para actualizar el comportamiento de transacción en sqlalchemy

if session.bind.name == 'sqlite': 
    session.execute('begin immediate transaction') 

antes de hacer la selección.

Esto parece funcionar por ahora, pero se siente como hacer trampa. ¿Hay una mejor manera de hacer esto?

+0

Esto es necesario cuando el grupo de conexiones es algo además de 'NullPool'; o dicho de otra manera, cuando el dsn es 'sqlite: ///: memory:'? – SingleNegationElimination

Respuesta

7

SELECCIONAR ... PARA ACTUALIZAR DE ... no es compatible. Esto es comprensible teniendo en cuenta la mecánica de SQLite en que el bloqueo de filas es redundante ya que toda la base de datos está bloqueada al actualizar cualquier parte de ella. Sin embargo, sería bueno si una versión futura de SQLite lo admite para SQL razones de intercajebilidad, nada más. La única funcionalidad requerida es para asegurar que se coloque un candado "RESERVADO" en la base de datos si aún no está allí.

extracto de http://sqlite.org/cvstrac/wiki?p=UnsupportedSql

i creo que hay que sincronizar el acceso a toda la base de datos. mecanismo de sincronización normal también debería aplicarse aquí bloqueo de archivos, sincronización de procesos, etc.

+1

Enlace más actualizado: http://sqlite.org/isolation.html. Ver resumen, punto 1: las transacciones en SQLite son SERIALIZABLE. – michauwilliam

Cuestiones relacionadas