Danjo's two cents NAV, Powershell, Android, C#, Lync, Win8, …

24Okt/140

NAV 2013 R2 – Änderungen werden erst nach Neustart des ServiceTiers aktiv

Diese Woche bin ich auf ein eher störendes Phänomen bei der Entwicklung in einer NAV 2013 R2 CU12 Datenbank gestosen. (Das verhalten konnte ich inzwischen auch in älteren Build-Versionen nachstellen)

Ich lege eine neue Tabelle an, erzeuge eine Page dazu und klicke auf RUN.

SQL-Fehler: Tabelle kann nicht gefunden werden.

Kurzer Blick auf dem Server, die Tabelle fehlt tatsächlich.

Export -> Lösche -> Import -> Tabelle fehlt

Sync-NAVTenant im Powershell aufrufen -> kein Fehler -> Tabelle fehlt

Neustart NST -> Tabelle fehlt -> Start RTC -> Tabelle wird angelegt

 

Diese Verhalten war Problemlos jederzeit reproduzierbar. Doch wo kam es her? An CU12 scheint es nicht zu liegen.

Fragen wir doch mal das Internet: Keine der üblichen Suchen bringt etwas das helfen könnte.

Dann hat es mir doch noch gedämmert: Es sieht so aus als ob der Trigger in der Object Metadata Tabelle fehlt.

Kurzer Blick: Stimmt, der ist nicht da.

 

Wie habe ich das den geschafft?

Mein Vorgehen war so:

- Neue Datenbank über SQL anlegen

- Import einer NAVDATA-Sicherung inkl. aller Objekte und Daten

 

In der Dev-Enviroment sieht alles gut aus. Der RTC läuft auch stabil.

 

Zum Schluß dann noch wie das ganze zu korrigieren ist:

Der Trigger lässt sich über SQL anlegen:

/****** Object: Trigger [dbo].[$ndo$objecttracking] Script Date: 23.10.2014 08:38:20 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE TRIGGER [dbo].[$ndo$objecttracking] ON [dbo].[Object Metadata] FOR DELETE, INSERT, UPDATE AS SET NOCOUNT ON DECLARE @delCount INTEGER, @insCount INTEGER, @updatedRows INTEGER, @currentDBTS BIGINT SELECT @delCount = COUNT(*) FROM DELETED SELECT @insCount = COUNT(*) FROM INSERTED SELECT @updatedRows = 0 SELECT @currentDBTS = CAST(@@DBTS AS BIGINT) IF (@insCount > 0) BEGIN UPDATE [dbo].[Object Tracking] SET [Object Timestamp] = @currentDBTS FROM INSERTED AS I JOIN [dbo].[Object Tracking] AS T ON (T.[Object Type] = I.[Object Type] AND T.[Object ID] = I.[Object ID] AND T.[Change Type] = 0) SELECT @updatedRows = @@ROWCOUNT IF (@updatedRows < @insCount) BEGIN INSERT INTO [dbo].[Object Tracking] ([Object Type], [Object ID], [Change Type], [Object Timestamp]) SELECT I.[Object Type], I.[Object ID], 0, @currentDBTS FROM INSERTED AS I LEFT OUTER JOIN [dbo].[Object Tracking] AS T ON (I.[Object Type] = T.[Object Type] AND I.[Object ID] = T.[Object ID] AND T.[Change Type] = 0) WHERE T.[Object Type] IS NULL AND T.[Object ID] IS NULL END END IF (@delCount > 0) BEGIN IF (@updatedRows = 0) BEGIN UPDATE [dbo].[Object Tracking] SET [Object Timestamp] = @currentDBTS FROM DELETED AS D JOIN [dbo].[Object Tracking] AS T ON (T.[Object Type] = D.[Object Type] AND T.[Object ID] = D.[Object ID] AND T.[Change Type] = 0) SELECT @updatedRows = @@ROWCOUNT END IF (@updatedRows < @delCount) BEGIN INSERT INTO [dbo].[Object Tracking] ([Object Type], [Object ID], [Change Type], [Object Timestamp]) SELECT D.[Object Type], D.[Object ID], 0, @currentDBTS FROM DELETED AS D LEFT OUTER JOIN [dbo].[Object Tracking] AS T ON (D.[Object Type] = T.[Object Type] AND D.[Object ID] = T.[Object ID] AND T.[Change Type] = 0) WHERE T.[Object Type] IS NULL AND T.[Object ID] IS NULL END END GO

12Okt/120

NAV 2009: Probleme mit korrupten / gelöschten METADATEN

Beim arbeiten mit Microsoft Dynamics NAV kann es passieren, dass die Metadaten eines Objektes korrupt sind.

Das ist an und für sich kein Problem, da die Metadaten immer dann neu erzeugt werden, wenn ich das Objekt über den Object Designer kompiliere. Aber wie sieht das bei den versteckten Systemtabellen aus?

Oder was fast noch schlimmer ist: Was mache ich, wenn ich versehentlich alle Metadaten gelöscht habe?

Dieses Problem lässt dich nur auf einem Weg korrekt lösen.

Erst öffnest du den "Alter Database"-Dialog und setzt die Datenbank in den single user Zustand.

Anschliessend wird das Kennzeichen Enable for Microsoft Dynamics NAV Server deaktiviert..

Wenn das alles durch ist setzt du den Haken wieder und kannst zuschauen wir der Client die Objekte (inklusive der Systemtabellen) kopmiliert. Ist dieser damit fertig muss die Datenbank nur noch für Benutzer wieder frei gegeben werden. (Single user wieder deaktivieren)

7Mrz/120

Object Change Listener

Da die Frage heute erneut aufkam, würde ich gerne kurz etwas zum Object Change Listener erzählen.

Seit dem Release von Microsoft Dynamics NAV 2009 gibt es nicht mehr die klassische Client/Server-Umgebung. Mit 2009 wurde der neue Rollenbasierte Client (RTC = Role Tailored Client) eingeführt. Dieser ist nur noch für die Anzeige der Daten zuständig, sämtliche Logik wird auf dem neuen Dienst Service Tier ausgeführt.

Wenn man nun in einer NAV 2009 Datenbank entwickelt kann es passieren, dass die Änderungen nicht im RTC auftauchen. Für Entwickler die auch schon in früheren Versionen mit mehrern Clients auf eienr Datenbank entwickelt haben ist dies vermutlich nichts Neues, allerdings hilft in diesem Fall der Neustart des Clients nicht weiter. Dadurch, dass wir nun das ServiceTier zwischen der Datenbank und dem RTC haben, ist ein Neustart des ServiceTiers notwendig.

Da es im Normalfall allerdings nur ein ServiceTier für mehrere Anwender gibt, sollte man dies nicht zu oft machen.

Natürlich ist sich Microsoft darüber im klaren und bietet mit dem Object Change Listener eine einfache Lösung hierfür an.

Besagter Object Change Listener tut nicht mehr und nicht weniger als die Objekte der Datenbank auf Änderungen hin zu überwachen. Wird ein Objekt geändert, so veranlasst er das ServiceTier sich das Objekt neu aus der Datenbank zu laden, anstatt das gecachte Objekt an den RTC zu übergeben.

Wann man diesen selbst einrichten muss und wie das funktioniert ist kurz und knackig in diesem MSDN-Beitrag beschrieben:

MSDN-Article: Activate Object Change Listener

Wenn man wissen möchte ob auf der aktuellen Datenbank der broker aktiviert ist, kann man dies in der sys.databases-Tabelle des SQL-Servers nachschauen. Dort gibt es das Feld is_broker_enabled, welches den aktuellen Status anzeigt (0 = aus, 1= ein).

   
%d Bloggern gefällt das: