Kar počne with v zvezi s povezavo na bazo je to, da poskrbi za ustrezno zaključevanje transakcije. Sledeča koda:
pov = dbapi.connect(...) # povezava na bazo - kakršnokoli že
with pov:
# nekaj počnemo na bazi
je torej (bolj ali manj) ekvivalentna temu:
pov = dbapi.connect(...) # povezava na bazo - kakršnokoli že
try:
# nekaj počnemo na bazi
pov.commit() # zaključimo transakcijo
except BaseException as ex: # nekaj je šlo narobe
pov.rollback() # prekličemo transakcijo
raise ex # vrnemo napako
Skratka, v primeru, da gre vse kot po maslu, imamo na koncu spremembe zapisane v bazo, če pa gre karkoli narobe, pa se celotna transakcija prekliče (tj., kot da ne bi počeli nič) in se sproži napaka, sama povezava pa ostane uporabna za nadaljnje poizvedbe (dokler ne pokličemo pov.rollback(), se namreč poizvedbe po napaki ne bodo izvajale!).
Seveda je to najbolj uporabno v primeru, ko nekaj spreminjamo na bazi - če bomo neko "atomarno" spremembo dosegli z več poizvedbami, naredimo zanje samo en pov.commit() oziroma jih vključimo pod isti with, da v primeru napake baza ne bo ostala v nekonsistentnem stanju. Seveda bomo včasih želeli ujeti napako in sami ustrezno ukrepati (npr. obvestiti uporabnika o napaki):
try:
with pov:
# nekaj počnemo na bazi
except dbapi.DatabaseError as ex: # prišlo je do napake na bazi - transakcija je sedaj preklicana
# ukrepamo ob napaki
Mimogrede, načeloma je čisto v redu, če v aplikaciji povezavo odpremo enkrat in jo pustimo odprto, dokler aplikacije ne zapremo - kot rečeno, z zgornjo uporabo se povezava ne zapre, tako da lahko večkrat naredimo with pov: ... za isto povezavo pov.