Universität Mannheim Lehrstuhl für Praktische Informatik III Thomas Neumann D7 27, Raum 415 68131 Mannheim Telefon: (0621) 181-2214 Email: [email protected] Transaktionssysteme 10. Übungsblatt, Sommersemester 2004 Lösungsvorschläge 1. Schreiben Sie ein Programm, das eine Einversionenhistorie sinnvoll in eine Mehrversionenhistorie umwandelt. import java.util.∗; class GenerateMV { public static void dumpMV(Schedule s) { Map commited=new HashMap(); Map used=new HashMap(); Map ids=new HashMap(); int nextId=1; for (int index=0;index<s.operations.length;index++) { if (index>0) System.out.print(” ”); Operation o=s.operations[index]; switch (o.operation) { case Operation.ABORT: System.out.print(”a”+o.transaction); break ; case Operation.COMMIT: { Map local=(Map)used.get(o.transaction); if ( local !=null) for ( Iterator iter =local.keySet(). iterator () ; iter .hasNext();) { Object key=iter.next(); Integer value=(Integer)local .get(key); if ((! commited.containsKey(key))||(((Integer)commited.get( key)).intValue()<value.intValue())) commited.put(key,value); } System.out.print(”c”+o.transaction); } break; case Operation.READ: case Operation.WRITE: { 1 Integer id=(Integer)ids.get(o.transaction) ; if (id==null) { id=new Integer(nextId++); ids .put(o.transaction , id) ; Map local=new HashMap(); used.put(o.transaction , local ) ; for (int index2=index;index2<s.operations.length;index2++) if ((s .operations[index2]. transaction==o.transaction)&& (s .operations[index2].operation==Operation.READ)) { Integer i=(Integer)commited.get(s.operations[index2]. element); if ( i==null) i=new Integer(0); local .put(s.operations[index2].element,i) ; } } if (o.operation==Operation.READ) { Map local=(Map)used.get(o.transaction); System.out.print(”r”+o.transaction+”[”+o.element+”,”+local. get(o.element)+”]”); } else { Map local=(Map)used.get(o.transaction); local .put(o.element,id) ; System.out.print(”w”+o.transaction+”[”+o.element+”,”+id+”] ”); } } break; } } System.out.println() ; } public static void main(String[] args) { if (args.length==0) { System.err. println (”usage: java ”+GenerateMV.class.getName()+” < schedule(s)>”); return; } for (int index=0;index<args.length;index++) { System.out.print(args[index]+”: ”); System.out.flush() ; // Einlesen Schedule sched; try { sched=Schedule.read(new java.io.BufferedReader(new java.io. FileReader(args[index]))); 2 } catch (java.io .IOException e) { System.out.println(”unable to open.”); e.printStackTrace(); return; } // Umwandeln dumpMV(SortTopologically.makeTotal(sched)); } } } 2. Warum ist eine solche Umwandlung sinnvoll? Welche Vorteile ergeben sich? Geben Sie ein Beispiel an. • Einversionenhistorie implizit • Mehrversionen erlaubt mehr Nebenläufigkeit • w1[x] r2[y] r2[x] c2 w1[y] c1 3. Wie können Mehrversionenhistorien effizient ausgewertet werden, wenn z.B. ARIES verwendet wird? • Schreiben: Normales Vorgehen. • Lesen: Lesesperre anfordern. Hält jemand anders eine Schreibsperre und hat die Daten geändert? Wenn nein, normal lesen, sonst neue Daten lesen und Undo-Record aus dem Log anwenden. • Problem: LSN pro Seite, Sperre pro Tupel ⇒ Log scannen 3