# Tabelle für "wiederkehrende Rechnungen"



## beta20 (10. Apr 2018)

Hallo zusammen, 

ich möchte gerne in meiner Applikation "wiederkehrende" Aufgaben oder Rechnungen speichern.
Die Frage ist jedoch, wie ich das modelliere.

Beispiel:
Ich möchte, dass jeden Tag um 12 Uhr eine Aufgabe generiert wird (z.B. eine Email an mich schicken etc.).
-> Ich kann ja nun nicht 1000 Einträge generieren für jeden Tag

Mein Gedankengang ist derzeit folgender:
- In meiner DB steht immer nur ein Eintrag für den nächsten Zeitpunkt, also z.B. morgen 12 Uhr.
- Sobald dies erledigt ist (ein Flag "Status o.ä.), wird automatisch ein neuer Eintrag für den nächsten Zeitpunkt angelegt.

Die zweite Frage ist dann wie die Aufgabe ausgeführt wird.
Meine Idee ist hier einen Schedule in meiner @EJB Container anzulegen, der alle 10 Minuten prüft, ob es Aufgaben gibt? Wenn ja, dann wird diese ausgeführt etc.

Oder gibt es andere Vorschläge?

Danke


----------



## Flynn (10. Apr 2018)

Wenn du ein Windows-Betriebssystem verwendest, dann nutze doch auch für deine Java-Applikation auch den Windows-JobScheduler für deine automatische EMail. Du findest den Scheduler unter "Systemsteuerung/Verwaltung/Aufgabenplanung". Ich nutze ihn ähnlich wie du es möchtest und es funktioniert super, daß ich 2x in der Woche zu einem bestimmten Zeitpunkt eine automatische EMail bekomme.


----------



## mrBrown (10. Apr 2018)

Das Unix-Äuivalent wäre Cron.

Ich bin mir aber noch nicht sicher, worum es dir eigentlich geht - geht es dir um das speichern in der Datenbank oder das passende zeitliche ausführen oder eine Mischung aus allem?


----------



## beta20 (10. Apr 2018)

das Verschicken einer Email war nur ein Beispiel - das ganze ist eine Webanwendung (JAVA EE), die auf einem Server läuft
Generell geht es mir darum, dass wiederkehrende Aufgaben in der DB abgespeichert werden soll
a) Wie soll hier die Tabelle aussehen?
b) Wie werden die Aufgaben angetriggert?


----------



## Flynn (10. Apr 2018)

Du könntest mit "Thread.sleep( 86400000 );" in einer Schleife so die perfekte zeitliche z.B. 24-stündige Wiederkehrung des Vorgangs erreichen. In einer Tabelle hinterlege neben einer IdNr, den Programmnamen oder eine Aufgabenbezeichnung, und im DateTime-Format eben wann du was passieren hast lassen, damit du auch den Aufgaben-Ablauf so gut verfolgen kannst. So koordiniere ich meinen Scheduler.


----------



## beta20 (10. Apr 2018)

ja aber wie speichere ich WANN welche Aufgabe ausgeführt wird?


----------



## Meniskusschaden (10. Apr 2018)

beta20 hat gesagt.:


> ja aber wie speichere ich WANN welche Aufgabe ausgeführt wird?


Was spricht denn gegen deinen eigenen Vorschlag aus dem Eröffnungsposting. Das:


beta20 hat gesagt.:


> Mein Gedankengang ist derzeit folgender:
> - In meiner DB steht immer nur ein Eintrag für den nächsten Zeitpunkt, also z.B. morgen 12 Uhr.
> - Sobald dies erledigt ist (ein Flag "Status o.ä.), wird automatisch ein neuer Eintrag für den nächsten Zeitpunkt angelegt.


wäre doch ein vernünftiger Ansatz.

Falls dein DB-System einen Scheduler hat, könntest du dort ein paar Tasks einplanen und dir ansehen, wie die gespeichert werden. Vielleicht kannst du dich daran orientieren. Bei MySQL kannst du es dir z.B. mit `select * from information_schema.events` anzeigen.


----------



## thecain (11. Apr 2018)

Oder mit jee boardmitteln: https://docs.oracle.com/javaee/6/tutorial/doc/bnboy.html


----------



## beta20 (11. Apr 2018)

ich bevorzuge auch eher die JEE Bordmitteln.
Kann ich hier jede Minute einen Schedule anstarten?
Was passiert wenn ein Schedule noch nicht alle Aufgaben abgearbeitet hat?
Fängt dann der nächste Schedule an und es gibt Probleme?


----------



## mrBrown (11. Apr 2018)

Flynn hat gesagt.:


> Du könntest mit "Thread.sleep( 86400000 );" in einer Schleife so die perfekte zeitliche z.B. 24-stündige Wiederkehrung des Vorgangs erreichen.


Ich hoffe sehr, dass das ein Witz ist...


----------



## mrBrown (11. Apr 2018)

beta20 hat gesagt.:


> a) Wie soll hier die Tabelle aussehen?


Hängt von den Aufgaben ab, wenn die regelmäßig wiederholt werden, könnte man zB einfach das Intervall speichern (und wenn nötig zusätzlich in einer anderen Tabelle alle schon ausgeführten).
Ansonsten wäre auch deine Variante ein Weg.



beta20 hat gesagt.:


> b) Wie werden die Aufgaben angetriggert?


die EE-Boardmittel dürften dabei die beste Wahl sein, würden ja auch schon von @thecain genannt.


----------



## beta20 (12. Apr 2018)

Wie wäre folgender Ansatz:

*Schedule_Intervall: (Speicherung des Intervall)*
- ID
- Name
- Beschreibung
- StartDate
- EndDate
- ScheduleType (By Day, By Week, By Month, By Year)
- Every_Minutes (-> integer)
- Every_Hours (-> integer)
- Every_Days (-> integer)
- Every_Weeks (-> integer)
- Every_Month (-> integer)
- Weekday_Monday (-> boolean)
- Weekday_Tuesday (-> boolean)
- Weekyday_... (-> boolean)
- Month_January
- Month_February
- ....

So könnte ich dann auch etwas anlegen, wie:
- Jeden *zweiten Donnerstag *im *April*
  = Every_Days = 2
  = Weekkay_Thursday = true
  = Month_April = true


*Schedule_Execution: (Speicherung der Ausführungen + nächste Ausführungen)*
- ID
- Schdule_Intervall_FK
- Status (successful, outstanding)

Im EJB - Container habe ich dann jede Minute einen Schedule laufen, der:
- Holt mir alle "outstanding" Schedules.
- Führt diese aus
- Legt nach der Ausführung einen neuen Eintrag in der Schedule_Execution an, der die nächste Ausführung speichert (mit dem Status "outstanding")*

*
Möchte jemand wirklich die nächsten Ausführungen (also mehr als nur den einen Eintrag sehen), könnte man diesen sich selbst als JAVA Objekte anhand der Schedule_Intervall - Tabelle generieren.

Passt dieser Ansatz?


----------



## mrBrown (12. Apr 2018)

beta20 hat gesagt.:


> *Schedule_Intervall: (Speicherung des Intervall)*


uU sind da noch Cron-Expressions einen Blick wert: https://docs.oracle.com/cd/E12058_01/doc/doc.1014/e12030/cron_expressions.htm
(was deinem ja auch nah kommt)


beta20 hat gesagt.:


> - Jeden *zweiten Donnerstag *im *April*


Das wäre damit `* * * ? 4 4#2`, wenn ich mich grad nicht irre (und könnte natürlich in eine besser lesbare Form überführt werden)



beta20 hat gesagt.:


> Im EJB - Container habe ich dann jede Minute einen Schedule laufen, der:
> - Holt mir alle "outstanding" Schedules.
> - Führt diese aus
> - Legt nach der Ausführung einen neuen Eintrag in der Schedule_Execution an, der die nächste Ausführung speichert (mit dem Status "outstanding")


Wenn möglich würde ich das nicht mit Polling lösen, kommt aber immer auf den Zweck an und ob das überhaupt möglich ist.
Für den Anfang dürfte das aber vermutlich reichen.



beta20 hat gesagt.:


> Möchte jemand wirklich die nächsten Ausführungen (also mehr als nur den einen Eintrag sehen), könnte man diesen sich selbst als JAVA Objekte anhand der Schedule_Intervall - Tabelle generieren.


Das würde ich auch so lösen.


----------

