Top Banner
42! … la risposta alle domande che non avete mai fatto
29

Django village talk 42

Aug 11, 2014

Download

Data & Analytics

Marco DePaoli

- Gestione delle transazioni: commit/rollback a livello di db, autocommit, atomic, commit on success, TransactionMiddleware, etc.
- Lock dei record in fase di modifica: lock acquisiti automaticamente da db, lock espliciti, lock ottimistici gestiti a livello applicativo
- Gestione delle connessioni: “persistent connections” in django o “connection pooling” con tool esterni (pgBouncer)
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Django village   talk 42

42!… la risposta alle domande che non avete

mai fatto

Page 2: Django village   talk 42

… e non sapevate di dover fare

Transaction (... be atomic, please)Locking (... be optimistic, please)Connection (... be persistent, please)

Page 3: Django village   talk 42
Page 4: Django village   talk 42
Page 5: Django village   talk 42

SQL-transactions

"An SQL-transaction (sometimes simply called a "transaction") is a sequence of executions of SQL-statements that is atomic with respect to recovery"

… a single atomic unit of work in a database

Page 6: Django village   talk 42
Page 7: Django village   talk 42

Nuclear power

Usato come decorator o come context manager:

transaction.atomic

è tuo amico

… ma occhio ai “percorsi non convenzionali”

Page 8: Django village   talk 42

transactions jazz

Nucleariziamo il progetto: ATOMIC_REQUESTDividiamo l’atomo: savepointsImpiliamo transazioni: nested atomic (TY 1.6!)

… e leggiamo qualcosa (prima di altri danni):Django Transactions

Transaction Management with Django 1.6django.db.transaction source

Page 9: Django village   talk 42

...to 1.6

togliere il TransactionMiddlewareusare ATOMIC_REQUESTS = True

… ma non è esattamente la stessa cosa

Page 10: Django village   talk 42
Page 11: Django village   talk 42
Page 12: Django village   talk 42

Martin Fowler - P of EAA● Optimistic Offline Lock (416)... "second save loses"

● Pessimistic Offline Lock (426)... "second read loses"

● [ Coarse Grained Lock (438), Implicit Lock (449) ]

Pessimistic, Optimistic and ... Cleese

Page 13: Django village   talk 42

"first save loses and user isn't notified"

Page 14: Django village   talk 42

It is a design issue!

Page 15: Django village   talk 42

Apps per Django

django-locking

“Prevents users from doing concurrent editing”

django-concurrency

“Optimistic lock implementation for Django.”

django-optimistic-lock

“Offline optimistic locking for Django.”

Page 16: Django village   talk 42
Page 17: Django village   talk 42

SAVE Snippet

rows = cls.objects.\filter(pk=self.pk, _change=self._change).\update(_change=self._change + 1)

if not rows:raise ConcurrentModificationError()

self._change += 1super(ConcurrentModel, self).save(*args, **kwargs)

Page 18: Django village   talk 42
Page 19: Django village   talk 42

Setupdrop table doctors;create table doctors(name char(20), is_available boolean);insert into doctors values ('alice', True);insert into doctors values ('tom', True);select * from doctors;

Session Alice-- begin;

Session Tom-- begin;

Session Aliceupdate doctors set is_available = False where name = 'alice'and (select count(1) from doctors where is_available=True) >= 2;commit;

Session Tomupdate doctors set is_available = False where name = 'tom'and (select count(1) from doctors where is_available=True) >= 2;commit;

Opps!

please try… and solve ;-)

Page 20: Django village   talk 42

Setupcreate table mytab(class integer, value integer);insert into mytab values (1, 10);insert into mytab values (1, 20);insert into mytab values (2, 100);insert into mytab values (2, 200);

Session Abegin;

Session Bbegin;

Session Aset transaction isolation level serializable;insert into mytab (class, value) select 1, sum(value) from mytab where class = 2;

Session Bset transaction isolation level serializable;insert into mytab (class, value) select 2, sum(value) from mytab where class = 1;

Session Acommit;

Session B (???)commit;

you can try this at home :-)

Optimistic Lock... at DB level

Page 21: Django village   talk 42
Page 22: Django village   talk 42
Page 23: Django village   talk 42

Connections

default: connect/disconnect for each requestproblem: 70 ms … 10 ms queryreason: ssl handshake, backend process, etc.solutions:

● persistent connection● connection pooling

Page 24: Django village   talk 42
Page 25: Django village   talk 42

Persistent connections

1. start/end request: close_old_connections2. foreach con: close_if_unusable_or_obsolete

a. close_atb. pingc. errors

3. CONN_MAX_AGE: 0, positive, None

Persistency - commit on github

Page 26: Django village   talk 42

pgBouncer

Page 27: Django village   talk 42
Page 28: Django village   talk 42

Unless you know how it works, you will write programs that corrupt data. It is that simple

—Concluding remark of the chapter on “Locking and Concurrency” in Tom Kyte’sbest-selling book, Expert One-On-One Oracle

“We suspect that numerous isolation errors occur each day at many large sites because of this, leading to corrupt data sometimes noted in data warehouse applications.” “Making Snapshot Isolation Serializable”

Alan Fekete: University of Sydney; N.S.W; Australia, 2006; [email protected]

Page 29: Django village   talk 42