14.10.2015, 09:45 | #1 |
Участник
|
One of great new functional features of Microsoft Dynamics NAV 2016 is preview posting. It allows you to preview all the entries that would result from posting a document or a general journal.
Preview posting is not a simple thing. If it was, Microsoft would have delivered it years ago. There must be something in particular with NAV 2016 that powers preview posting, so I decided to investigate it and see exactly how it works. I am not particularly happy with what I found out, but I have also learned some valuable lessons from it. In this post, I’ll share my findings. Functionally, preview posting looks like this:
So – this must be all there is to it? Unfortunately, it isn’t. Even though it could have been possible to achieve this with at least two different approaches, preview posting actually uses a new feature, which – after a closer look – seems to have been specifically tailored to power the preview posting. Your guess? Yes – TryFunction. If you look at codeunit 81 (for example; I’ll use sales posting routine for all examples in this post) you can see that its Code function is turned into a TryFunction. It is called directly from the OnRun trigger, but it’s called with the IF NOT Code THEN construct in the Preview function. Here’s the Preview function: It does several things:
Well, you don’t even have to customize anything – there is (what seems like) a bug in codeunit 80 which results in a COMMIT being called even during preview posting. Now, this surely is a bug, and I am sure in a cumulative update, this code will read: Anyway, since this COMMIT is in there, all you need to do is switch Calc. Inv. Discount on, release a sales order, and preview post it, and – voilà: Now, I haven’t seen this error in my entire NAV career. I knew it existed, and it was there to prevent posting unbalanced transactions into G/L, but seeing it on screen would mean you seriously messed up with your code. Now, in the course of a few days, I see it two times. But why does this error show? It’s certainly unexpected. Knowing that CONSISTENT is called at a single place in codeunit 12, where it marks transaction as inconsistent as long as it doesn’t balance to 0 (which certainly isn’t the case with PreviewPosting) you may be confused and wonder if there is some other CONSISTENT call. A few seconds of investigation will reveal that there is one – right at the beginning of the Start function in codeunit 19: Here, it unconditionally marks the transaction as inconsistent, right at the beginning of the whole posting process. Why does it do so? In C/AL transaction is committed to the database in two situations:
You may imagine, codeunit 19 never sets CONSISTENT(TRUE) – it simply leaves the record as inconsistent for the duration of transaction. If there are no COMMITs, the transaction will be aborted either by a legitimate posting error, or by the silent abort at the very end. However, this CONSISTENT(FALSE) at the very beginning makes sure that no commits are accidentally called – if they are, the consistency check will result in failure. And that’s it. No way you can cause accidental catastrophe by injecting a COMMIT or throwing an error at a wrong place. If you have read my last post, about the dangers of TryFunction, and if you agree with it (and everyone I spoke to agrees) – then something is wrong. If an error happens inside a TryFunction nothing is rolled back. This behavior is dangerous, and yet – without it – preview posting couldn’t work. If data was rolled back, then nothing would be left in the database for the Finish function in codeunit 19 to collect. As I said earlier, there are at least two approaches to preview posting, without unnecessary (and utterly confusing for end users) CONSISTENT(FALSE), and without excessive refactoring of posting routines – and I’ll explain each of the two approaches in two separate posts, one on Thursday, and one on Friday this week – so stay tuned. In the meantime, there is one useful takeaway from this whole analysis: there is a way to make sure that failure in any TryFunction does not create mess in the database. It’s pulling the same CONSISTENT trick that Microsoft pulled in the Preview Posting feature, just on a smaller scale. Now, what I am going to show is ugly, dirty, and I hate even being forced to blog about that. But with the current state of TryFunction feature, this is the best shot: The mechanics are simple – at the beginning of the TryFunction, you mark the transaction as inconsistent. In case TryFunction fails, the transaction will remain marked as inconsistent in case you forget to rollback the data yourself. If TryFunction succeeds, then transaction is marked as consistent again, so that transaction can be successfully committed, when time is ripe. However, as I said – this is ugly. Any COMMIT anywhere in the code will slice this approach to ribbons. And this proves once again that TryFunction behavior – as it currently is – of not rolling back data, is absolutely wrong and that any architecture (including Preview Posting) that depends on it, is inherently bad. Anyway, I hope you learned a thing or two from this post, as have I while digging through the code. No animals were harmed during the making of this post, even though a few were quite close to it. Read this post at its original location at http://vjeko.com/tryfunction-lessons...review-posting, or visit the original blog at http://vjeko.com. 5e33c5f6cb90c441bd1f23d5b9eeca34The post TryFunction Lessons Learned from Preview Posting appeared first on Vjeko.com. </img> </img> Читать дальше
__________________
Расскажите о новых и интересных блогах по Microsoft Dynamics, напишите личное сообщение администратору. |
|