|
| Mønster for at generere et unikt id Fra : Morten |
Dato : 11-01-03 18:08 |
|
Hej. Jeg skal bruge et mønster til at generere en unik primær
nøgle, id af typen number i en Oracle DB (sequences må ikke
benyttes).
Tilgangen til DB'en foregår gennem Java, men det mønster jeg
leder efter er ganske sikkert generelt.
Jeg forestiller mig noget a la:
private static long id = -1;
public static synchronized long getUniqueID() {
if(id == -1) {
String sql = "SELECT max(id) FROM table";
..
id = resultSet.getLong(1);
}
return ++id;
}
Forslag eller kommentarer?
Pft,
Morten
| |
Jesper Louis Anderse~ (11-01-2003)
| Kommentar Fra : Jesper Louis Anderse~ |
Dato : 11-01-03 23:30 |
|
On Sat, 11 Jan 2003 18:07:34 +0100, Morten <usenet@kikobu.com> wrote:
>
> Hej. Jeg skal bruge et mønster til at generere en unik primær
> nøgle, id af typen number i en Oracle DB (sequences må ikke
> benyttes).
Hvorfor ikke sequences?
--
Jesper
| |
Kjeld Flarup (12-01-2003)
| Kommentar Fra : Kjeld Flarup |
Dato : 12-01-03 14:06 |
|
Morten wrote:
>
> Hej. Jeg skal bruge et mønster til at generere en unik primær
> nøgle, id af typen number i en Oracle DB (sequences må ikke
> benyttes).
Er det fordi andre kilder kan generere et id også? Ellers er sequences perfekte.
> Jeg forestiller mig noget a la:
> private static long id = -1;
> public static synchronized long getUniqueID() {
> if(id == -1) {
> String sql = "SELECT max(id) FROM table";
> ..
> id = resultSet.getLong(1);
> }
> return ++id;
> }
Du skal inden du kalder lave en select update på id, således at en anden process
ikke kommer og returnerer den samme værdi. Det er derfor sequences er meget bedre.
--
------------------------- Med Liberalistiske Hilsner --------------------------
Civilingeniør, Kjeld Flarup - Mit sind er mere åbent end min tegnebog
Ådalen 8, Mogenstrup, 7800 Skive, Tlf: 40 29 41 49, Fax: 96 95 74 48
Den ikke akademiske hjemmeside for liberalismen - www.liberalismen.dk
| |
Morten (12-01-2003)
| Kommentar Fra : Morten |
Dato : 12-01-03 14:38 |
|
Kjeld Flarup wrote:
> Morten wrote:
>> public static synchronized long getUniqueID() {
>> if(id == -1) {
>> String sql = "SELECT max(id) FROM table";
>> ..
>> id = resultSet.getLong(1);
>> }
>> return ++id;
>> }
>
>
> Du skal inden du kalder lave en select update på id, således at en anden
> process ikke kommer og returnerer den samme værdi. Det er derfor
> sequences er meget bedre.
Ovennævnte metode er "synchronized", det er en Java mekanisme der
garanterer at der kun er een proces inde i metoden.
SELECT .. FOR UPDATE låser vel også hele tabellen?
Mvh Morten
| |
Kjeld Flarup (13-01-2003)
| Kommentar Fra : Kjeld Flarup |
Dato : 13-01-03 13:39 |
|
Morten wrote:
> Ovennævnte metode er "synchronized", det er en Java mekanisme der
> garanterer at der kun er een proces inde i metoden.
Den krølle havde jeg ikke lige set.
> SELECT .. FOR UPDATE låser vel også hele tabellen?
Det er den i følge sagens natur nødt til at gøre.
--
------------------------- Med Liberalistiske Hilsner --------------------------
Civilingeniør, Kjeld Flarup - Mit sind er mere åbent end min tegnebog
Ådalen 8, Mogenstrup, 7800 Skive, Tlf: 40 29 41 49, Fax: 96 95 74 48
Den ikke akademiske hjemmeside for liberalismen - www.liberalismen.dk
| |
Peter Makholm (12-01-2003)
| Kommentar Fra : Peter Makholm |
Dato : 12-01-03 14:42 |
|
Morten <usenet@kikobu.com> writes:
> Hej. Jeg skal bruge et mønster til at generere en unik primær
> nøgle, id af typen number i en Oracle DB (sequences må ikke
> benyttes).
Det kunne være noget med at du bruger nøglen som sessionsnøgle og
helst ikke vil gøre det muligt at stjæle sessioner?
> private static long id = -1;
>
> public static synchronized long getUniqueID() {
Prøv at lede efter noget der genererer UUID'er:
< http://www.dsps.net/uuid.html>
Hvis du på google søger efter "Java uuid" så får de et par klasser der
ser ud til at implementerer noget du kan bruge som getUniqueID.
--
Peter Makholm | First you fall in love with Antarctica, and then it
peter@makholm.net | breaks your heart
http://hacking.dk | -- Antarctica
| |
Claus Rasmussen (12-01-2003)
| Kommentar Fra : Claus Rasmussen |
Dato : 12-01-03 14:45 |
|
Morten wrote:
> Hej. Jeg skal bruge et mønster til at generere en unik primær
> nøgle, id af typen number i en Oracle DB (sequences må ikke
> benyttes).
Det er dumt, hvis sequences ikke må benyttes, da du nu skal til
at løse en masse problemer, som Oracle allerede har klaret for
dig. F.eks:
> private static long id = -1;
>
> public static synchronized long getUniqueID() {
>
> if(id == -1) {
> String sql = "SELECT max(id) FROM table";
> ..
> id = resultSet.getLong(1);
> }
>
> return ++id;
> }
Dur' ikke. Hvis der er to processer, der samtidigt udfører din
SQL sætning, vil de begge få samme id tilbage.
Der er i stedet to andre måder, det kan gøres på, men hvilken,
du skal bruge, afhænger af præcist, hvilke faciliteter den
java, du bruger, har.
Hvis der er support for RETURNING_CLAUSE er det nemt. Så laver
du en tabel - ID_TABEL - med præcist een række, der rummer det
sidste id, der blev uddelt, og skriver noget i denne stil:
String sql = "UPDATE id_tabel SET id = id + 1 RETURNING
id INTO id_var";
Hvis der er support for at spørge til antal rækker, der er
blevet opdateret af en given transaktion, kan du gøre sådan
her:
String sql1 = "SELECT max(id) from ID_TABEL";
<udfør sql1>
id = resultSet1.getLong(1);
String sql2 = "UPDATE ID_TABEL set id = id + 1
where id = <det id du lige har selected>";
<udfør sql2 og commit>
if (resultSet2.rows_affected() = 1)
<vores id er ok>
else
<vores id er _ikke_ ok - om igen>
Pas i øvrigt på med transaktioner. Hvis du aktiverer oven-
stående inde i en anden transaktion bliver det ret langhåret.
-Claus
| |
|
|