9ProgrammierungvonDB-Anwendungen Informationssysteme für Ingenieure (ISI) Herbstsemester 2016 R.Marti AnwendungsprogrammeimKontext “PowerUser” (Parametric)User Interpreterfor “adhoc” QueriesandUpdates UserInterfaceLayer UserInterfaceLayer BusinessLogicLayer BusinessLogicLayer PersistencyLayer PersistencyLayer PersistencyLayer DatabaseManagementSystem(DBMS) Focus ApplicationProgrammer “Generic”PersistencyLayer Database DatabaseAdministrator R.Marti ISI2016 -- 09Programmierung vonDB-Anwendungen 2 TypischeDienstleistungenvonDatenbanksystemen • persistenteVerwaltungsehrgrosserDatenmengen(Terabytes)auf Sekundärspeicher,inkl.Fehlertoleranz(backup,recovery) Focus • deklarativer,mengenorientierterDatenzugriff • Mehrbenutzerbetrieb(concurrencycontrol) • Datenintegritätskontrolle(semanticintegrity) • Zugriffskontrolle,Datenschutz(authorization) • OptimierungderDatenzugriffeundAnfragen (accesspathselection,queryoptimization) • DatenunabhängigkeitvonProgrammen(dataindependence) – beiÄnderungenphysischerDatenstrukturenundZugriffsoptimierung – beiErweiterungenundModifikationenlogischerDatenstrukturen R.Marti ISI2016 -- 09Programmierung vonDB-Anwendungen 3 SQLÜberblick • DataDefinitionLanguage(DDL) – DefinitionvonTabellen,Sichten:CREATETABLE,CREATEVIEW,DROP,ALTER – DefinitionvonIntegritätsbedingungen:CREATEASSERTION,DROP • DataManipulationLanguage(DML) – Datenbank-Anfragen:SELECT – Datenbank-Änderungen:INSERT,UPDATE,DELETE • DataControlLanguage(DCL) Focus – z.B.Authorisierung:GRANT,REVOKE • SchnittstellenzuProgrammiersprachen – viaPrecompiler:EmbeddedSQL,SQLJ – viaprozeduraleSchnittstelle:CLI(z.B.ODBCfürC),JDBCfürJava • ProzeduraleElemente:SQL/PSM(bzw.PL/SQLinOracle,…) – z.B.CREATEPROCEDURE R.Marti ISI2016 -- 09Programmierung vonDB-Anwendungen 4 KopplungvonProgrammier- undDatenbanksprachen • DieAusdruckskraftdeklarativerDatenbanksprachen(wiez.B.SQL)reichtfürdie ProgrammierungvielerAnwendungennichtaus. • MöglichkeitenzurKopplungvonProgrammiersprachenundDatenbanksprachen – ErweiterungeinerProgrammiersprachemitdeklarativenSprachelementenfürdenDatenbankZugriff z.B.Pascal/R(UHamburg),PS-Algol(UGlasgow),PJava(Sun+UGlasgow) – ErweiterungeinerDatenbanksprachemitprozeduralenSprachelementen(Prozeduren,if, while,…)fürAllzweck-Programmierung z.B.PL/SQL (Oracle),Transact-SQL (Sybase,Microsoft);SQL/PSM-Standard – EinbettungvonDatenbankanweisungeninAllzweckProgrammiersprache(z.B.COBOL,C,Java), diesog.Wirtssprache(hostlanguage) EmbeddedSQL,SQLJ Focus – ProzeduraleSchnittstelle:ODBC bzw.SQL/CLI,JDBC R.Marti ISI2016 -- 09Programmierung vonDB-Anwendungen 5 HerausforderungenbeiderAnbindungvonDatenbanken • WiewerdenDatenzwischenProgrammenundDBMSausgetauscht? • Wiekönnen(potentiellstrukturierte)DatentypengängigerProgrammiersprachen aufdieskalaren(„atomaren“)DatentypenvonSQLabgebildetwerden? • WiewerdenSQLNULL-WerteinProgrammenverarbeitet? • WiegeschiehtdieTypprüfunganderSchnittstelleeinesProgrammszumDBMS bzw.zuSQL? • WiekanneinProgrammeinepotentiellsehrgrosse(Antwort-)Mengevon Datensätzenverarbeiten? • WieteiltdasDBMSeinemProgrammmit,dassein(odergarmehrere,etwabeim EinfügenmehrererneuerZeilen)Fehleraufgetretensind? R.Marti ISI2016 -- 09Programmierung vonDB-Anwendungen 6 ZugriffaufDatenbanken:Überblick DB-Verbindung eröffnen “Preliminaries” SQL-Anweisung “erzeugen” SQL-Anweisung ausführen beiINSERT/UPDATE/DELETE-Statement: MeldungüberAnzahlbetroffenerTupel Connection Statement bei SELECT-Statement: ResultSet,inSQLCursor genannt: MengevonTupelnmitZeigeraufnächstesTupel nächstesResultatTupelholen Resultatmenge “freigeben” evt.Transaktion abschliessen DB-Verbindung schliessen R.Marti ISI2016 -- 09Programmierung vonDB-Anwendungen 7 ProzeduraleDatenbank-Schnittstellen:ODBCundJDBC • ODBC • – vonMicrosoftdefinierterStandardfürSQL-DBZugriffausC – GrundlagedesSQL-CLIStandards JDBC – vonSun(2009vonOracleerworben)definierterStandardfürSQL-DBZugriffausJava – TeilderJ2EE(Java2EnterpriseEdition)Plattform – unabhängigvonDB/DBMSdankDriverManager,derfürjedesDBMSeinenpassendenDriver ladenkann,derStandardJDBCSQLindenDialektdesjeweiligenDBMSübersetzt Driver Manager Anwendung R.Marti Driver Driver DBServer DBServer ISI2016 -- 09Programmierung vonDB-Anwendungen Database Database 8 ZugriffaufDBmitJDBC:Überblick Class.forName DriverManager.getConnection 2 1 con.createStatement st.executeUpdate st.executeQuery rs.next Erklärungen: 1) LadebenötigtenDriver 2) EröffneVerbindung (+setzedanachevt. gewissePropertiesder Verbindung) 3) “Avanciere”denZeigerin derResultatmenge 4) Holeeinzelne Attributwertedes aktuellenTupels 3 rs.getString con.commit con.rollback 4 rs.close con.close R.Marti ISI2016 -- 09Programmierung vonDB-Anwendungen 9 AusführeneinerAnfrage(Pseudocode) Send the following query to the DBMS: SELECT OrderDate, PrdDescr, Qty FROM Orders o, Products p WHERE o.PrdNo = p.PrdNo AND CusNo = value of variable n ; while there are unprocessed rows in the result of the above query do Get the next unprocessed row and make it the current row ; valDat = the value of column OrderDate of the current row ; descr = the value of column PrdDescr of the current row ; qty = the value of column Qty of the current row ; Process these values (e.g., print them) ; end; Note: NamesinbluearenamesofJavavariables. NamesinredarenamesofSQLcolumns(andtables). R.Marti ISI2016 -- 09Programmierung vonDB-Anwendungen 10 JDBC:AusführeneinerAnfrage // assumption: con is connection to DBMS try { Statement st = con.createStatement(); String q = "SELECT OrderDate, PrdDescr, Qty " + "FROM Orders o, Products p " + "WHERE o.PrdNo = p.PrdNo AND CusNo = "; // assumption: CNo is in variable n ResultSet rs = st.executeQuery(q + n); String valDat; String descr; long qty; System.out.println("orders for customer number " + n); while (rs.next()) { valDat = rs.getString(1); // or: rs.getString("OrderDate") descr = rs.getString(2); qty = rs.getLong(3); System.out.println("date " + valDat + ", description " + descr + ", quantity " + qty); } rs.close(); st.close(); } catch (SQLException e) { e.printStackTrace(); } R.Marti ISI2016 -- 09Programmierung vonDB-Anwendungen 11 AusführeneinerÄnderungstransaktion(Pseudocode) // assumption: oNo contains a order number Send the following query to the DBMS: SELECT PrdNo, Qty, Status FROM Orders WHERE OrdNo = value of variable oNo ; Get the single result row and make it the current row ; Get the column values of the row and put them into variables pNo , qty, and status ; if status = '1 ordered' then Send the following update to the DBMS: UPDATE Products SET Stock = Stock - value of variable qty WHERE PrdNo = value of variable pNo AND Stock >= value of variable qty ; Send the following update to the DBMS: UPDATE Orders SET Status = '2 shipped' WHERE OrdNo = value of variable oNo ; end ; R.Marti ISI2016 -- 09Programmierung vonDB-Anwendungen 12 JDBC:AusführeneinerÄnderungstransaktion con.setAutoCommit(false); String q = "SELECT PrdNo, Qty, Status FROM Orders WHERE OrdNo = ?"; PreparedStatement qryOrder = con.prepareStatement(q); // prepareStatement: see next slide String up = "UPDATE Products SET Stock = Stock - ? WHERE PrdNo = ? AND Stock > ?"; PreparedStatement updPrdStock = con.prepareStatement(up); String uo = "UPDATE Orders SET Status = ′2 shipped′ WHERE OrdNo = ?"; PreparedStatement updOrdStatus = con.prepareStatement(uo); ? ist Platzhalter für Input-Parameter // assumption: variable oNo contains order number try { qryOrder.setLong(1, oNo); ResultSet rs = qryOrder.executeQuery(); rs.next(); long pNo = rs.getLong(1); long qty = rs.getLong(2); String status = rs.getString(3); if (status.equals("1 ordered")) { updPrdStock.setLong(1,qty);updPrdStock.setLong(2,pNo);updPrdStock.setLong(3,qty); int n = updStock.executeUpdate(); updOrdStatus.setLong(1, oNo); n = updOrdStatus.executeUpdate(); con.commit(); // tell DBMS that we think that all changes were successfully performed } } catch (SQLException e) { con.rollback(); // tell DBMS that an error occurred and any changes performed should be undone } R.Marti ISI2016 -- 09Programmierung vonDB-Anwendungen 13 JDBC:StatementundPreparedStatement Statement wirdfüreinmaligeAusführungeiner PreparedStatement wirdfürmehrfache Anweisungverwendet: AusführungeinerAnweisungverwendet: st = con.createStatement(); rs = st.executeQuery("SELECT … "); st = con.prepareStatement("SELECT … "); rs = st.executeQuery(); bzw.: bzw.: st = con.createStatement(); n = st.executeUpdate("DELETE … "); st = con.prepareStatement("DELETE … "); n = st.executeUpdate(); DamitkanneineFormvon”Precompilation”simuliert werden. “Input”ParameterwerdendurchdenMarker? gekennzeichnetunddessenWertemitden MethodensetXXX(position,value) gesetzt “Output”ParameterwerdendurchdieKolonnennameninderSELECT-Klauselbezeichnetund mitdenMethodengetXXX(position) bzw.getXXX(name) gelesen wobeiXXX füreinenJavaDatentyp steht,aufdenderSQLDatentyp abgebildetwerdenkann. R.Marti ISI2016 -- 09Programmierung vonDB-Anwendungen 14 JDBC:DynamischesSQL try { Statement st = con.createStatement(); // assumption: table name is in variable tname ResultSet rs = st.executeQuery("SELECT * FROM " + tname); ResultSetMetaData md = rs.getMetaData(); int colCount = md.getColumnCount(); System.out.println("contents of table " + tname); for (int i = 1; i <= colCount; i++) { System.out.print(md.getColumnName(i) + " "); } System.out.println(" "); while (rs.next()) { for (int i = 1; i <= colCount; i++) { System.out.print(rs.getString(i) + " "); } System.out.println(" "); } rs.close(); st.close(); } catch (SQLException e) { e.printStackTrace(); } R.Marti ISI2016 -- 09Programmierung vonDB-Anwendungen holeObjekt,das dieResultatmenge beschreibt AnzahlAttribute derTupelinder Resultatmenge Namedesi-ten Attributs 15 Transaktionskonzept EineTransaktion isteineFolgevon(Lese- undÄnderungs-)Operationenaufeiner Datenbank,dieausAnwendungssichtzusammengehören.ModerneDB-Systeme garantierendiesog.ACID EigenschaftenvonTransaktionen: • Atomicity (Atomarität) DieÄnderungeneinerTransaktionwerdenentwedervollständigodergarnicht durchgeführt.ImFehlerfalloder“aufWunscheinesProgramms”werdenbereits durchgeführteÄnderungeneinerTransaktionrückgängiggemacht. • Consistency (ErhaltungderKonsistenzbzw.Integrität) EineTransaktiontransformiertdieDatenbankvoneinemkonsistentenZustandineinen anderenkonsistentenZustand(bez.spezifizierterIntegritätsbedingungen). • Isolation (Isolation;ÄquivalenzzumEinbenutzerbetrieb) EineTransaktionsiehtdieDatenbankso,alsgäbeeskeineparallelablaufenden Transaktionen,unddieÄnderungenderTransaktionwerdenbiszumAbschlussder TransaktionvorparallelenTransaktionenverborgen. • Durability (Dauerhaftigkeit) DieÄnderungeneinerabgeschlossenenTransaktiongehenauchimFehlerfallnicht verloren. R.Marti ISI2016 -- 09Programmierung vonDB-Anwendungen 16 DemarkationdesUmfangseinerTransaktion • IntheoretischenArbeitenwirdderUmfangeinerTransaktiondurch – BOT:BeginOfTransaction – EOT:EndOfTransaction(erfolgreichesEndeeinerTransaktion) – RBT:RollBackTransaction(AbbruchundEndeeinerTransaktion) gekennzeichnet. ErstimSQL:1999StandardwirdeinexplizitesBOTerwähnt. • InderSQLPraxisgiltjedochdassogenannte„chainedtransactionmodel“: – BOT istimplizit: einemProzesswirdeineTransaktionzugeordnetsofernihmzurZeiteines Daten-Zugriffs(SELECT FOR UPDATE,INSERT,UPDATE,DELETE) keineaktiveTransaktionzugeordnetist – EOT wirddurchAusführungeinerexplizitenCOMMIT Anweisungsignalisiert – RBT wirddurchAusführungeinerexplizitenROLLBACK Anweisungsignalisiert odererfolgtimplizitsoferneinProzessohneexplizitesCOMMIT /ROLLBACK terminiert(z.B.durcheinShutdowndesDB-Servers) R.Marti ISI2016 -- 09Programmierung vonDB-Anwendungen 17 BeispielfürTransaktionen:DB-Schemaund-Zugriffe(mitSQLJ) Relationenschema:Accounts(AccNo, CusNo, BranchNo, Balance) class Accounts { public long getBalance(int aNo) { // read a row long bal; #sql { SELECT Balance INTO :bal FROM Accounts WHERE AccNo = :aNo }; return bal; } public void setBalance(int aNo, long newBal) { // write a row #sql { UPDATE Accounts SET Balance = :newBal WHERE AccNo = :aNo }; } public long getTotalBal(int cNo) { // read rows // return total balance of customer with id cNo long totBal; #sql { SELECT SUM(Balance) INTO :totBal FROM Accounts WHERE CusNo = :cNo }; return totBal; } } R.Marti ISI2016 -- 09Programmierung vonDB-Anwendungen InSQLJwerdenSQL Deklarationenund Anweisungendurch #sql { … }; geklammert InSQLJwerden Programm-Variablenmit NamenvarName durch :varName referenziert. SELECT column INTO :varName nurmöglichfürsog. “singlerowSELECT” 18 BeispielfürTransaktionen:EineeinfacheTransaktion public boolean transfer(int fromAcc, int toAcc, long // invariant: sum of balances of fromAcc and toAcc try { // --- debit fromAcc --long bal = Accounts.getBalance(fromAcc); // bal = bal – amt; if (bal < 0) { #sql { ROLLBACK WORK }; return false; // failure } Accounts.setBalance(fromAcc, bal); // // --- credit toAcc --bal = Accounts.getBalance(toAcc); // Accounts.setBalance(toAcc, bal + amt); // #sql { COMMIT WORK }; return true; // success } catch (SQLException e) { #sql { ROLLBACK WORK }; return false; // failure } } R.Marti ISI2016 -- 09Programmierung vonDB-Anwendungen amt) { read a row write a row read another row write another row 19 ZuvermeidendeProbleme:VerlusteinerÄnderung Prozess1 Prozess2 (InkarnationdesgleichenProzesses) Bank.transfer(111, 333, 100) Bank.transfer(222, 333, 200) // --- debit fromAcc --// --- debit fromAcc --... ... assumption: balance of account 333 is 1000 // --- credit toAcc --// --- credit toAcc --bal = Accounts.getBalance(toAcc); balance of account 333 is 1000 // --- credit toAcc --bal = Accounts.getBalance(toAcc); balance of account 333 is 1000 Accounts.setBalance(toAcc,bal+amt); balance of account 333 is 1200 (=1000+200) Accounts.setBalance(toAcc,bal+amt); balance of account 333 is 1100 (=1000+100) - instead of 1300 ZugriffaufgleichesKonto VerlusteinerÄnderung(LostUpdate) R.Marti ISI2016 -- 09Programmierung vonDB-Anwendungen 20 ZuvermeidendeProbleme:InkonsistentesLesen Prozess4 Bank.transfer(111, 333, 800) Prozess5 creditcheckdesKunden99 mitKonti111und333 assumption: balance of account 111 is 1500, balance of account 333 is 1200, total balance is 2700 // --- debit fromAcc --bal = Accounts.getBalance(fromAcc); bal = bal – amt; Accounts.setBalance(fromAcc,bal); balance of account 111 is 700 (=1500−800), balance of account 333 is 1200, total is 1900 tot = Accounts.getTotBal(99); total balance of accounts 111 and 333 is 1900 at this point if (tot < 2000) { println("not enough credit"); } // --- credit toAcc --bal = Accounts.getBalance(toAcc); Accounts.setBalance(toAcc,bal+amt); balance of account 111 is 700, balance of account 333 is 2000 (=1200+800), total balance is 2700 ZugriffaufgleichesKonto InkonsistentesLesen(InconsistentRead) R.Marti ISI2016 -- 09Programmierung vonDB-Anwendungen 21 ZuvermeidendeProbleme:KaskadierendesZurücksetzen Prozess6 depositamountonaccountwithnumber222 Prozess7 transferamountfromaccount222 toaccount333 ... ... // --- credit toAcc --bal = Accounts.getBalance(toAcc); Accounts.setBalance(toAcc, bal+amt); Bank.transfer(222, 333, 200); #sql { COMMIT WORK }; // // // // // before this change COMMITs, an unexpected ROLLBACK happens (e.g. due to server shutdown) so that the account balance is reset to original balance ZugriffaufgleichesKonto SpezialfalldesinkonsistentenLesens: RollbackisteineFormdesSchreibens) R.Marti ISI2016 -- 09Programmierung vonDB-Anwendungen 22 SchedulesundSerialisierbarkeit • Formalisierung: EinSchedule isteineFolgevonLese- undSchreibaktionenvonObjekten(meistensrows), diedurchverschiedenequasi-parallelablaufendeProzesse(Transaktionen)ausgeführt werden. DieLese- undSchreibaktionenwerdenwiefolgtdargestellt: - AktionRi (x): Transaktioni liest(reads)Objektx - AktionWi (x): Transaktioni schreibt(writes)Objektx ManchmalwerdenauchnochdiefolgendenAktionenaufgrführt: - AktionCi : Transaktioni endeterfolgreich(commits) - AktionAi : Transaktioni wirdabgebrochen(aborts,d.h.esgibteinenrollback) • KorrektheitskriteriumfürSchedules:Serialisierbarkeit EinSchedulemit2verschiedenenTransaktioneni undj istserialisierbar, fallsderScheduleäquivalentistzueinemseriellenSchedule,d.h.einSchedulebeidem - zuerstalleAktionendereinenTransaktionund - danachalleAktionenderanderenTransaktionausgeführtwerden R.Marti ISI2016 -- 09Programmierung vonDB-Anwendungen 23 CharakterisierungderProblemfälle • Beispiel eines(zwar„verzahnten“aber)serialiserbarenSchedules: - Transaktion3 überweisteineSummevonacc222 zuacc444 (andrereKonti!) - Transaktion5 führteinenCreditCheckaufacc111 undacc333 aus(vgl.frühereFolie) Schedule:R3 (acc222) , W3 (acc222) , R5 (acc111) , R5 (acc333) , R3 (acc444) , W3 (acc444) ÜberweisungundCreditChecksindtrotz„verzahnterAusführung“korrekt undäquivalentzu2möglichenseriellenSchedules: - Trans.3 vor5:R3 (acc222) , W3 (acc222) , R3 (acc444) , W3 (acc444) , R5 (acc111) , R5 (acc333) - Trans.5 vor3:R5 (acc111) , R5 (acc333) , R3 (acc222) , W3 (acc222) , R3 (acc444) , W3 (acc444) Diesgiltjedochnicht fürTransaktionen4 und5 (vgl.„InkonsistentesLesen“): Schedule:R4 (acc111) , W4 (acc111) , R5 (acc111) , R5 (acc333) , R4 (acc333) , W4 (acc333) • Problemekönnensichergeben,wenneinScheduleKonfliktpaareenthält: EinKonfliktpaar entsteht,fallsAktionen von2verschiedenenTransaktionenaufdasgleiche Objekt x zugreifenundeinederbeidenAktioneneineWrite-Aktion ist. Beispiele:R1 (x) → W2 (x) , W1 (x) → R2 (x) ,W1 (x) → W2 (x) (Keine Konfliktpaaresindz.B.R1 (x) → R2 (x) , R1 (x) → W1 (x) , W1 (y) → R2 (x) ) R.Marti ISI2016 -- 09Programmierung vonDB-Anwendungen 24 FormalisierungderBeispiele • VerlusteinerÄnderung: Schedule: ... , R1 (acc333) , R2 (acc333) , W2 (acc333) , W1 (acc333) Konfliktpaare: R1 (acc333) → W2 (acc333) R2 (acc333) → W1 (acc333) • InkonsistentesLesen: Schedule: R4 (acc111) , W4 (acc111) , R5 (acc111) , R5 (acc333) , R4 (acc333) , W4 (acc333) Konfliktpaare: W4 (acc111) → R5 (acc111) R5 (acc333) → W4 (acc333) • KaskadierendesZurücksetzen: Schedule: R6 (acc222) , W6 (acc222) , R7 (acc222) , W7 (acc222) , R7 (acc333) , W7 (acc333) , W6 (acc222) Konfliktpaare: R6 (acc222) → W7 (acc222) W6 (acc222) → R7 (acc222) W6 (acc222) → W7 (acc222) R7 (acc222) → W6 (acc222) W7 (acc222) → W6 (acc222) R.Marti ISI2016 -- 09Programmierung vonDB-Anwendungen 25 VonderMengederKonfliktpaarezumPräzedenzgraph • AusderMengederKonfliktpaareeinesScheduleskanndersogenanntePräzedenzgraph fürdiebeteiligtenTransaktionenhergeleitetwerden. DabeibesagteinKonfliktpaareinerderFormen Ri (x) → Wj (x) oderWi (x) → Rj (x) oderWi (x) → Wj (x) dassdieTransaktioni vorderTransaktionj ablaufenmuss. DieswirdimPräzedenzgraphdurcheineKanteTi → Tj bzw.,nochkürzer, durcheineKantei → j angezeigt. Wenn(undnurwenn)derPräzedenzgraphZyklenenthält, dannsinddieTransaktionenimZyklusnichtserialisierbar. • Beispiel„InkonsistentesLesen“: Konfliktpaare: Präzedenzgraph: W4 (acc111) 4 R.Marti → R5 (acc111) , R5 (acc333) 5 → W4 (acc333) inWorten: Trans.4mussvorTrans.5ablaufen undTrans.5mussvorTrans.4ablaufen ISI2016 -- 09Programmierung vonDB-Anwendungen 26 SystemunterstützungderACIDEigenschaften • AtomaritätundDauerhaftigkeit DieseEigenschaftenwerdendurchdasFühreneinesLogsaufDisk unterstützt.Beieinem SystemCrashwirdanhanddesLogsentschieden,ob - ÄnderungenaufDiskrückgängiggemachtwerdenmüssen,oderob - ÄnderungennochaufDisknachgeführtwerdenmüssen • Konsistenz InnereKonsistenz(z.B.KonsistenzderDateninTabellenunddenzugehörgenIndex-Daten) undEinhaltungdeklarierterIntegritätsbedingungenwirdvomSystemsichergestellt WeitereBedingungenmussderProgrammierersicherstellen(vgl.Geldtransfer). • Isolation IsolationwirdinderPraxisz.B.durchSperren(locking)betroffenerDatenobjekte wieTupel oderBlöckevonTupeln(sog.Blöckebzw.Seiten,vgl.DBMSArchtektur)erreicht: - Lesezugriff(SELECT):shared(S)lock,erlaubtnurLesezugriffdurchandereProzesse - Schreibzugriff(INSERT,UPDATE,DELETE):exclusive(X)lock Dabeiwirddasstrikte2Phasen-Sperrprotokoll verwendet: alleacquiriertenSperrenwerdenbiszumEndederTransaktiongehalten. R.Marti ISI2016 -- 09Programmierung vonDB-Anwendungen 27 Folgendesstrikten2-PhasenSperrprotokolls • JemehrDatenobjektegelesenwerdenundjelängereineTransaktiondauert,umsogrösser istdieWahrscheinlichkeit,dassdiegehaltenenSperrenzuWartezeitenodergar Verklemmung(deadlock,sieheunten)führen • EineTransaktionsolltemöglichstwenigeDatenobjektelesenundschreiben. • DieDauereinerTransaktionsolltesokurzwiemöglichsein; insbesonderesollteinnerhalbeinerTransaktionnichtaufBenutzer-Inputgewartetwerden. • WenneineTransaktionT1 aufdieFreigabeeinesDatenobjektswartet,dasdurchTransaktion T2 gesperrtwurdeundT2 seinerseitsaufdieFreigabeeinesDatenobjektswartet,dasdurch TransaktionT1 gesperrtwurde,danntritteineVerklemmung(deadlock)auf. WenndasDB-SystemeinenDeadlockentdeckt,dannwirdeinederbeteiligtenTransaktionen vomDB-Systemabgebrochen(abortbzw.rollback); indieserSituationsolltedieTransaktionmehrfachversuchtwerden ➛ JobdesAnwendungsprogrammierers. R.Marti ISI2016 -- 09Programmierung vonDB-Anwendungen 28 EliminationderBenutzerinteraktionausTransaktion do { #sql { SELECT Stock INTO :qoh FROM Products WHERE PNo = :pno }; #sql { COMMIT WORK }; // release lock on product System.out.println("There are " + qoh + "items on hand"); do { qty = GUI.prompt("How many do you want?"); } while (qty > qoh); // qty>qoh: user wants more than on hand #sql { UPDATE Products SET Stock = Stock - :qty WHERE PNo = :pno AND Stock >= :qty // still enough on hand? }; } while (SQLSTATE == NOTFOUND); // retry if not enough on hand R.Marti ISI2016 -- 09Programmierung vonDB-Anwendungen 29 HandlingvonDeadlocks numRetries = 0; do { #sql { UPDATE Customers SET Discount = 1.1*Discount WHERE City = ′Geneva′ }; // assume there are lots of customers // => potential for deadlock if (SQLSTATE == SERIALIZATION_FAILURE) { aborted = TRUE; #sql { ROLLBACK WORK }; numRetries = numRetries + 1; // wait for 1 second } else { aborted = FALSE; #sql { COMMIT WORK }; } } while (aborted && numRetries < 5); R.Marti ISI2016 -- 09Programmierung vonDB-Anwendungen 30