Questo sito utilizza cookie per le proprie funzionalità e per inviarti pubblicità e servizi in linea con le tue preferenze. Chiudendo questo banner, scorrendo questa pagina o cliccando qualunque suo elemento acconsenti all’uso dei cookie.

Accedendo al link http://www.odoo-italia.org/index.php/home/cookie-policy puoi leggere in dettaglio le modalità di trattamento dei cookie da parte dell'Associazione Odoo Italia.

Benvenuto, Ospite
Nome utente: Password: Ricordami

ARGOMENTO: [9.0][Solved] Transazioni "manuali"

[9.0][Solved] Transazioni "manuali" 2 Anni 4 Mesi fa #25706

  • pablo
  • Avatar di pablo
  • Offline
  • Junior Boarder
  • Messaggi: 36
  • Karma: 0
Per questioni di affidabilità in certi casi ho bisogno di gestire manualmente le transazioni. In questo caso devo fare l'import di diversi documenti testata-dettaglio e vorrei che ogni N documenti importati la transazione venga chiusa e ne venga aperta una nuova che importa i successivi N.

In questo modo se alla transazione X mi viene sollevata una eccezione per un constraint non rispettato, sono sicuro che i documenti delle transazioni da 0 a X-1 sono stati salvati correttamente e non devo cominciare tutto da zero.

Usare un cr.commit() secco leggo che è giustamente sconsigliato. Qual'è il metodo migliore?

Possibilmente se mi fate uno snippet di codice esempio così si chiarisce meglio, grazie :)
Ultima modifica: 2 Anni 4 Mesi fa da pablo.
L\'Amministratore ha disattivato l\'accesso in scrittura al pubblico.

[9.0] Transazioni "manuali" 2 Anni 4 Mesi fa #25711

  • gigidn
  • Avatar di gigidn
  • Offline
  • Platinum Boarder
  • Messaggi: 1925
  • Ringraziamenti ricevuti 446
  • Karma: 22
Le insert son omogenee tutte in sql?

In ogni caso seppur sconsigliato io in alcuni casi lo faccio, unica accortezza invalidare la cache dopo ogni commit ....

Se usi gli oggetti potrebbe essere un pelo piu' complicato e non l'ho mai testato.
@KTec
www.ktec.it
L\'Amministratore ha disattivato l\'accesso in scrittura al pubblico.

[9.0] Transazioni "manuali" 2 Anni 4 Mesi fa #25724

  • pablo
  • Avatar di pablo
  • Offline
  • Junior Boarder
  • Messaggi: 36
  • Karma: 0
gigidn ha scritto:
Le insert son omogenee tutte in sql?

In ogni caso seppur sconsigliato io in alcuni casi lo faccio, unica accortezza invalidare la cache dopo ogni commit ....

Se usi gli oggetti potrebbe essere un pelo piu' complicato e non l'ho mai testato.

usare la query sql raw non ho voluto provarci perché mi interessava mantenere il layer ORM in modo da avere anche i vari costraint del caso (quelli su write, create, etc).

Utilizzare il cursore "stock" è molto rischioso perché chiudi una transazione che poteva avere delle scritture che avvengono dopo il tuo metodo e quindi lasci il db in uno stato inconsistente (vedi post dopo), dovresti essere 100% sicuro che nulla avviene dopo il tuo metodo, e con un ERP è molto complicato saperlo viste le tante strutture coinvolte.

Ho trovato una soluzione semplice quanto elegante (la prima risposta) che sinceramente adoro :)
with openerp.api.Environment.manage():
    with openerp.registry(self.env.cr.dbname).cursor() as new_cr:
        # Create a new environment with new cursor database
        new_env = api.Environment(new_cr, self.env.uid, self.env.context)
        # with_env replace original env for this method
        self.with_env(new_env).write({'name': 'hello'})  # isolated transaction to commit
        new_env.cr.commit()  # Don't show a invalid-commit in this case
    # You don't need close your cr because is closed when finish "with"
# You don't need clear caches because is cleared when finish "with"

I commenti spiegano già tutto molto bene ma in pratica si crea un nuovo cursore e nuovo ambiente temporanei dove possiamo gestire la nostra transazione in tutta tranquillita senza il rischio di lasciare inconsistente il database.

Plus: La concorrenza tra le transazioni è assicurata dal DBMS, l'isolation level scelto da openerp odoo è il "REPEATABLE READ".
Ultima modifica: 2 Anni 4 Mesi fa da pablo.
L\'Amministratore ha disattivato l\'accesso in scrittura al pubblico.

[9.0] Transazioni "manuali" 2 Anni 4 Mesi fa #25730

  • pablo
  • Avatar di pablo
  • Offline
  • Junior Boarder
  • Messaggi: 36
  • Karma: 0
pablo ha scritto:
Utilizzare il cursore "stock" è molto rischioso perché chiudi una transazione che poteva avere delle scritture che avvengono dopo il tuo metodo e quindi lasci il db in uno stato inconsistente, dovresti essere 100% sicuro che nulla avviene dopo il tuo metodo, e con un ERP è molto complicato saperlo viste le tante strutture coinvolte.

ho scritto una mezza cavolata, nel senso che si, è rischioso fare commit sul cursore che ti ritrovi nell'oggetto; in parte molti si sono salvati perché poi dopo tutto è finito bene (e non ci sono stati rollback).

Questo perché di base il cursore "di Odoo" non è autocommittante e quindi quando si fa un commit, i dati vengono scritti, ma la transazione rimane aperta. Le successive scritture vanno a buon fine ma se poi viene fatto un rollback, vengono cestinate tutte le scritture che erano in pending dall'ultimo commit in poi, quindi quelle prima sono ormai memorizzate sul DB.

Esempio:

Il client fa una chiamata RPC verso il metodo pippo
def pippo(self):
    create_1
    create_2
    create_3
    cr.commit()
    write_1
    write_2
    // errore
    cr.rollback()
    cr.close()

quando l'esecuzione del codice raggiunge il cr.rollback(), le due write (write_1, write_2) non vengono applicate sul database, ma la rollback si ferma li, poiché tutto ciò che è stato fatto prima del cr.commit() (create_1,create_2,create_3) ormai è permanente.
Il database quindi è in uno stato inconsistente

La soluzione corretta è quella del post sopra.
Ultima modifica: 2 Anni 4 Mesi fa da pablo.
L\'Amministratore ha disattivato l\'accesso in scrittura al pubblico.
Tempo creazione pagina: 0.133 secondi

Odoo Italia Associazione - C.F: 94200470485 - Sede: Viale dei Cadorna, 83 - Firenze - Italy

Protected by R Antispam