Locks behouden na commit

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Big Womly
  • Registratie: Oktober 2007
  • Laatst online: 01-09 13:39

Big Womly

Live forever, or die trying

Topicstarter
In een multi user/multi threaded omgeving wil ik in een Oracle database een bepaald record locken zodat andere users/threads deze niet kunnen bereiken.

SQL:
1
select column_names from table_name where conditions for update nowait


De tabel waar het over gaat is een queue waar een aantal pending opdrachten in staan. Een van de kolommen in die tabel is het aantal pogingen dat er zijn gebeurd om de opdracht uit te voeren.
De opdracht kan falen omdat er data ontbreekt, en in dat geval werkt het perfect, maar het kan ook gebeuren dat de opdracht langer dan 5 minuten duurt. In dat geval verliest de applicatie zijn connectie met de database en worden alle wijzigingen gerollbackt.

Vermits dit ook als een poging moet tellen wil ik dus
1) lock op de table zetten
2) het aantal pogingen met 1 verhogen
3) die verhoging al committen zonder mijn lock te verliezen
4) opdracht uitvoeren
5) volledige commit + unlock.

Alleen, bij een commit wordt er automatisch geunlocked en ben ik dus mijn garantie kwijt dat andere threads deze data niet locken voor hun gebruik.

Zelf had ik al gedacht om de tabel uit te bereiden met een "in-use" flag of een andere manier die de status van het record bijhoudt, maar het zou beter zijn indien ik het op een nettere manier kan oplossen.

When you talk to God it's called prayer, but when God talks to you it's called schizophrenia


Acties:
  • 0 Henk 'm!

  • P_de_B
  • Registratie: Juli 2003
  • Niet online
Ik zie niet direct in wat er aan een eigen flag niet netjes is. Geforceerd een lock van de db gebruiken lijkt me juist minder goed. Waarom denk je dat die oplossing minder is, welke nadelen zie je?

Oops! Google Chrome could not find www.rijks%20museum.nl


Acties:
  • 0 Henk 'm!

  • Big Womly
  • Registratie: Oktober 2007
  • Laatst online: 01-09 13:39

Big Womly

Live forever, or die trying

Topicstarter
Het nadeel van de flag is, wanneer de tool na 5 minuten zijn connectie verliest, die flag nog steeds aan staat en dat dit record dus nooit meer verwerkt gaat worden
Bedenk ik nu net
Tenzij ik een timestamp als flag ga gebruiken, maar dan moet ik ervan uitgaan dat de maker van de tool die ik uitbreid niet op een bepaald moment beslist om de tijdsspanne te verhogen naar 10 minuten bijvoorbeeld.

When you talk to God it's called prayer, but when God talks to you it's called schizophrenia


Acties:
  • 0 Henk 'm!

  • matthijsln
  • Registratie: Augustus 2002
  • Laatst online: 13:59
Je tool kan toch eerst de flag zetten, committen, het werk doen en daarna een nieuwe connectie maken om de flag weer terug te zetten?

Het probleem wat je dan wel hebt is als je proces crasht en de flag nooit meer terugzet. Normaliter is het voldoende om door welgemikte try/catch ervoor te zorgen dat die code altijd wordt uitgevoerd en regelmatig een rapportje te draaien met onverwerkte records (kan je wel timestamp bij gebruiken). Wil je meer zekerheid is er een hele sloot aan message queue middleware die mogelijk een optie is.

Acties:
  • 0 Henk 'm!

  • CubicQ
  • Registratie: September 1999
  • Laatst online: 07:41
Twee gedachten die nu in me opkomen, zonder er echt heel lang over nagedacht te hebben:
- Nested transactions
- Tweede connectie gebruiken die de eerste lock legt

Overigens heb ik alleen ervaring met het gebruik maken van een paar extra kolommen die de status weergeven van longrunning processes.

Acties:
  • 0 Henk 'm!

  • Big Womly
  • Registratie: Oktober 2007
  • Laatst online: 01-09 13:39

Big Womly

Live forever, or die trying

Topicstarter
De tool waarmee gewerkt moet worden werkt op basis van acties. Aan het begin van de actie legt deze een connectie met de database en als de actie is afgewerkt wordt er gecommit en wordt de connectie verwijderd. Als er iets verkeerd loopt of na 5 minuten is de actie nog niet voltooid, dan wordt er gerollbackt en wordt de connectie weer verwijderd.

Manueel een connectie leggen met de database is volgens mij inderdaad de enige oplossing, alleen jammer dat het niet op de voorgeschreven manier dan gaat.

Nested transactions lijkt mij dan een iets betere oplossing, maar zover ik zie lijkt het mij niet native ondersteund te zijn door de tool en daardoor niet realiseerbaar.

Alle DB manipulaties zouden in principe via de beschikbare actions in de tool moeten gebeuren. Zo is er een action Add, een action Edit en een action Delete die ik moet gebruiken in plaats van insert, update en delete from.


Conclusie:
Het is of manueel een connectie met de DB leggen, of niet realiseerbaar.

Thanks guys! :)

When you talk to God it's called prayer, but when God talks to you it's called schizophrenia

Pagina: 1