Avatar billede sjh Nybegynder
11. januar 2004 - 01:34 Der er 37 kommentarer og
1 løsning

Problemer med LOCK og UNLOCK TABLES

Jeg har problemer med LOCK og UNLOCK TABLES når jeg bruger dem her:

LOCK TABLES tabelnavn WRITE
gør noget...
UNLOCK TABLES

er der ikke nogle andre som kan skrive til tabelnavn. Det er også godt nok, men hvis 2 køre samme php-script på en gang så er der kun en som for lov til at skrive, den anden får ikke skrævet til databasen bagefter :( og må sende en post igen :(

finden der ikke en anden måde man kan låse et php-script på
ligesom i ASP Application.Lock og .Unlock
Avatar billede detox Nybegynder
11. januar 2004 - 01:53 #1
Hvorfor låse tabellen?
Avatar billede sjh Nybegynder
11. januar 2004 - 01:56 #2
for ikke at skrive i samme ID
Avatar billede detox Nybegynder
11. januar 2004 - 01:58 #3
Jamen det kan du jo risikere alligevel, hvis nr. 2 script sender posten igen og har valgt samme ID.
Avatar billede sjh Nybegynder
11. januar 2004 - 02:02 #4
Ja det var også derfor jeg godt kunne bruge noget i stil med ASP Application.Lock og .Unlock (den låser hele siden så der ikke er nogle der får adgang til siden før .Unlock er kørt)
Avatar billede detox Nybegynder
11. januar 2004 - 02:10 #5
Det ved jeg ikke om det er muligt, jeg har ikke hørt om det.
Avatar billede Slettet bruger
11. januar 2004 - 02:38 #6
Kan du ikke bare lave et autonummer-felt, så får det ikke samme ID.
Avatar billede detox Nybegynder
11. januar 2004 - 02:44 #7
Mon ikke der er tale om UPDATES?
Avatar billede detox Nybegynder
11. januar 2004 - 02:48 #8
Ellers må det være muligt at lave en workarround. Fx en tabel der styrer om en given tabel er ledig eller ej.
Avatar billede Slettet bruger
11. januar 2004 - 02:54 #9
Hvilken MySQL-version taler vi om? Hvis den er nyere end 4.0.5, kan du måske bruge en InnoDB-tabel med transactions i stedet for.
Avatar billede Slettet bruger
11. januar 2004 - 02:58 #10
Jeg havde lige set forkert. InnoDB tabeller er med som standard fra MySQL 4.0, og hvis du bruger en Mysql-Max, er den med fra 3.23.34a.
Avatar billede sjh Nybegynder
11. januar 2004 - 03:01 #11
MySQL-version: Jeg ved det faktis ikke det er her: http://www.b-one.net/

Jeg har forsøgt at lave en lille script som kunne klare det men det funker vist ikke helt.. den kommer ikke ud af lopp igen :D

<?
  function script_lock() {
    while(file_exists("lock.script")) {
    }
    fopen("lock.script", "w");
  }

  function script_unlock() {
    unlink("lock.script");
  }
?>
<?
  script_lock();

  script_unlock();
?>
Avatar billede sjh Nybegynder
11. januar 2004 - 03:10 #12
MySQL-version: Client API version 3.23.58
Avatar billede Slettet bruger
11. januar 2004 - 03:12 #13
Du kan prøve at lave en tabel af typen InnoDB, og derefter kontrollere om den også blev lavet som InnoDB. Hvis den gjorde, kan du bruge transactions, og det er meget smartere end at låse hele tabellen.
Avatar billede sjh Nybegynder
11. januar 2004 - 03:16 #14
Ja nu er jeg ikke så god til det der SQL ting... jeg ville heller have 2 funktioner som kunne låse et scrip på samme måde som den jeg fusker med :D script_lock() script_unlock()
Avatar billede detox Nybegynder
11. januar 2004 - 03:20 #15
Jeg har rettet din lock.script lidt til og tilføjet en timelimit på 10 minutter i det tilfælde at der skulle gå noget skævt:

<?
function script_lock() {
  if (file_exists("lock.script") && fileatime("lock.script")>(time()-600)) {
    return false;
  } else {
      touch("lock.script");
    return true;
  }
}
function script_unlock() {
  unlink("lock.script");
}

if (script_lock() === true) {
  // Do your stuff
  script_unlock();
}
?>
Avatar billede Slettet bruger
11. januar 2004 - 03:23 #16
Kan du forklare mere nøjagtigt, hvad det er for en slags databaseopdateringer, der bliver foretaget?

Det kan være vi kan finde på noget med et felt i databasen, som kan gøre det hele meget nemmere.
Avatar billede Slettet bruger
11. januar 2004 - 03:24 #17
Og den metode med filen er altså rimelig skrøbelig.
Avatar billede detox Nybegynder
11. januar 2004 - 03:29 #18
Jeg bryder mig heller om fil udgaven. Det ville være meget smartere kun at låse den række der bliver brugt istedet for hele tabellen. Som sandbox er inde på vha. MySQL.
Hvis du vælger at bruge det med filen skal du være opmærksom på, hvis der bruges mere end fx de 10 minutter er du nødt til at bruge en ny touch() inden.
Avatar billede sjh Nybegynder
11. januar 2004 - 03:32 #19
problemet er når 2 opretter en post i databasen på en gang.. så er det kun den ene post som bliver tilføjet...

vi kan bruge eksempel som her på eksperten.. når der er 2 som poster noget på en gang, så bliver bægge poste opret...

har før været ude for at der går 5-10 sek før jeg for en side når jeg har postet noget
Avatar billede detox Nybegynder
11. januar 2004 - 03:34 #20
Nej, ikke hvis du bruger autoincrement. Så bliver de begge tilføjet. Jeg troede der var tale om en UPDATE!
Avatar billede Slettet bruger
11. januar 2004 - 03:35 #21
Hvis det er INSERT i tabellen, så har du lavet noget på en helt forkert måde, hvis 2 brugere kommer til at konflikte med hinanden. Der skal du bruge et autonummerfelt og mysql_insert_id()
Avatar billede sjh Nybegynder
11. januar 2004 - 03:36 #22
okææ men hvad gør jeg så hvis det er en update ;)
Avatar billede Slettet bruger
11. januar 2004 - 03:38 #23
Det er meget lettere at hjælpe, hvis vi ser koden.

Ellers kan vi bare sige: Sæt ID feltet til at blive autoincremented og brug mysql_insert_id() hvis dit php-script har brug for at kende ID på den netop oprettede post.
Avatar billede sjh Nybegynder
11. januar 2004 - 03:39 #24
den kente jeg ikke "mysql_insert_id()" er det så bare mysql_insert_id("INSERT....");
Avatar billede Slettet bruger
11. januar 2004 - 03:40 #25
Nej. Først laver du din INSERT

Derefter siger du

$id=mysql_insert_id();
Avatar billede detox Nybegynder
11. januar 2004 - 03:42 #26
Det eneste problem med UPDATE kunne være at to brugere brugte tid på at opdatere den samme række samtidig. Den konflikter ikke, men den ene har selvfølgelig spildt sin tid.
Avatar billede Slettet bruger
11. januar 2004 - 03:43 #27
Nu begynder jeg at blive forvirret: Er der tale om UPDATE eller INSERT?
Avatar billede sjh Nybegynder
11. januar 2004 - 03:44 #28
det er det her jeg skal bruge det til:

<?php
  $strComment = fix_right_newline($_POST["question_text"]);
  if ($_POST["username"] && $strComment && $_POST["qtitle"] && $_POST["qcat"]) {
    $conn = mysql_connect(HOST, USER, PASS);
    mysql_select_db(DB);
    $query = mysql_query("INSERT INTO ".QUESTION_TABLE."(Datenum, Title, Category, Username, Question) VALUES('".date_int()."','".$_POST["qtitle"]."','".$_POST["qcat"]."','".$_POST["username"]."','".$strComment."');");
    $query = mysql_query("SELECT ID FROM ".QUESTION_TABLE." WHERE Category = '".$_POST["qcat"]."' ORDER BY ID DESC LIMIT 1;");
    $row = mysql_fetch_array($query);
    $ret_id = $row["ID"];
    mysql_close($conn);
    header("Location: $REDIRECT_URL?id=".$ret_id);
      } else {
    header("Location: $REDIRECT_URL");
  }
?>
Avatar billede Slettet bruger
11. januar 2004 - 03:46 #29
Så laver du bare disse linier:

    $query = mysql_query("SELECT ID FROM ".QUESTION_TABLE." WHERE Category = '".$_POST["qcat"]."' ORDER BY ID DESC LIMIT 1;");
    $row = mysql_fetch_array($query);
    $ret_id = $row["ID"];

om til:

$ret_id=mysql_insert_id();
Avatar billede Slettet bruger
11. januar 2004 - 03:47 #30
Og MySQL sørger selv for, at der ikke er to, der får samme ID. Det lader nemlig til at du allerede har sat ID til at være et autonummerfelt.
Avatar billede detox Nybegynder
11. januar 2004 - 03:50 #31
Det er en pæn 'chunk' du kan undvære der ;o)
Avatar billede sjh Nybegynder
11. januar 2004 - 03:50 #32
ok jeg ser på det... tak for hjælpen :-)
Avatar billede detox Nybegynder
11. januar 2004 - 03:53 #33
Ja, det gør jo en forskel. Vi kunne have sparet meget tid, hvis du havde reageret på: 02:44:36.
Avatar billede Slettet bruger
11. januar 2004 - 04:03 #34
detox: Og tænk på al den låse-kode der så heller ikke er nødvendig.

sjh: Det er generelt en god ide at beskrive sit problem meget grundigt og præcist. Så er det nemlig meget lettere for os andre at give præcis den hjælp, der er brug for.

Dette gælder især, hvis man er ude i noget, hvor man er lidt usikker, for det kan jo være at man er kommet ud af et sidespor, som du var her.

Hvis du havde postet den kode i selve spørgsmålet den 22/12 kunne du have haft det løst allerede dengang. detox ville nok have kommet med samme svar, som jeg gav dig lige før i sit første indlæg i http://www.eksperten.dk/spm/442688
Avatar billede sjh Nybegynder
11. januar 2004 - 04:09 #35
Jo men jeg var faktis mere ude efter en funktion som ASP Application.Lock og .Unlock men det ser ikke ud til at PHP kan det :(
Avatar billede Slettet bruger
11. januar 2004 - 04:10 #36
Ikke så vidt vi ved, men jeg kan nu heller ikke komme på noget, hvor det skulle være nødvendigt.
Avatar billede sjh Nybegynder
11. januar 2004 - 04:18 #37
Jo hvis fx. der skulle skrives til en file.. så der ikke er 2 som skriver i samme linje :)

Application.Lock
...skriv tilfile
Application.UnLock

hvis der så er 2 som køre det samme script på en gang, så tager den en bruger af gangen (altså scriptet kan kun køres af en bruger afgangen så venter den bare til en bruger er færtig)
Avatar billede Slettet bruger
11. januar 2004 - 04:41 #38
Der kan man låse filen, der skal skrives til. PHP-funktionen dertil hedder flock()
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Vi tilbyder markedets bedste kurser inden for webudvikling

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester