web
You’re offline. This is a read only version of the page.
close
Skip to main content

Notifications

Announcements

Community site session details

Community site session details

Session Id :
Finance | Project Operations, Human Resources, ...
Answered

Why do I get 'Call to TTSCOMMIT without first calling TTSBEGIN' here

(0) ShareShare
ReportReport
Posted on by 329
I have the following extension of a formDS:
 
 
[ExtensionOf(FormDataSourceStr(EssLeaveRequestEntry, LeaveRequest))]
final class FM_FormDS_EssLeaveRequestEntry_LeaveRequest_Extension
{
    public boolean save()
    {
        ttsbegin;
        Info(/TEST/);
        boolean ret = next save();
        ttsabort;
     }
}
 
I myself am not calling ttscommit, so Im wondering where the error comes from.
 
Other solutions I tried are:
-moving both ttsbegin and ttsabort after the next save() call
-moving both ttsbegin and ttsabort before the next save() call
-only calling ttsabort before the next save() call
-only calling ttsabort after the next save() call
 
All of them nicely block the save action, which is what I want, except I always get the error. How can I solve this?
I have the same question (0)
  • Verified answer
    Mohamed Amine Mahmoudi Profile Picture
    26,767 Super User 2026 Season 1 on at
      
    you must use try catch exception 
    Exemple :
    try
    {
         ttsBegin;
         //Code
         ttsCommit;
    }
    catch
    {
         ttsAbort;
    }
    Best regards,
    Mohamed Amine Mahmoudi
  • Martin Dráb Profile Picture
    238,599 Most Valuable Professional on at
    The verified answer is wrong. The code does nothing useful and causes a problem.
     
    If an exception is thrown (at least most types), the transaction is rolled back automatically before reaching the catch block, therefore ttsabort there has nothing to abort. That's why ttsabort is almost never used.
    And the problem is the catch block handles the exception and instead of interrupting execution on failure, it'll continue as if no exceptions occurred. You should rethrow the exception if there was a reason to have try/catch block at all.
     
    Regarding your actual problem, you mentioned an error, but you didn't tell us what the error was. Please give us more details (where is occurs, what the error message says).
     
    If you have unbalanced ttsbegin/ttscommit, the problem might be caused by some other code. It's also possible that your transaction is aborted inside next save().
    I recommend you don't try to create a DB transaction in the form at all. If you explain what you're trying to achieve, we may be able to suggest a better solution.
  • Superbunny Profile Picture
    329 on at
    @Martin Dráb:
    Thank you for your response.
     
    What I am trying to achieve:
    When a leaverequest is created, updated or deleted, there may be a reason based on logic for me to want to 'block' that create/update/delete.
    To achieve this I extended the save method mentioned above. I come from a history of normal web development and so far it seems to me that in D365 development I can often halt a process where I am in by calling ttsabort.
     
    What I hope to achieve here is logic in the following structure:
     
    *Perform my logic check that in the end returns a boolean
    *If true -> cancel the create/update/delete action  (this particular code is used only for create/update, but I would do the same for the code used for delete logic)
    *If false -> do nothing and let code continue
     
  • Suggested answer
    Martin Dráb Profile Picture
    238,599 Most Valuable Professional on at
    No, you don't halt code execution by calling ttsabort. That aborts the DB transaction and let code execution to continue, which will cause the error about unbalanced ttsbegin/ttscommit when trying to commit the transaction.
     
    Please forget that ttsabort exists; it's extremely rarely. That you're using it regularly means that you're doing it wrong.
     
    The usual place to check if a record can be saved or deleted is validateWrite() and validateDelete() methods. Use the table methods if possible. If the logic is specific to a particular form, use validateWrite()/validateDelete() methods of the form data source.
     
    If you want to stop code execution, throw an exception (throw error(...)). As already mentioned, this rollbacks the DB transaction as well.
  • Suggested answer
    Superbunny Profile Picture
    329 on at
    @Martin Drab:
     
    Sadly I could not use the table methods as the LeaveRequest.validateWrite() method does not give me access to the updated leaverequest pre-update.
    (since when you update a leaverequest a NEW leaverequest record is created, without a reference to the old one. This is why I was extending the form)
     
    I could however indeed replace my save extension by a validateWrite extension of the formdatasource, so that works! thank you

Under review

Thank you for your reply! To ensure a great experience for everyone, your content is awaiting approval by our Community Managers. Please check back later.

Helpful resources

Quick Links

Responsible AI policies

As AI tools become more common, we’re introducing a Responsible AI Use…

Congratulations to our 2025 Community Spotlights

Thanks to all of our 2025 Community Spotlight stars!

Leaderboard > Finance | Project Operations, Human Resources, AX, GP, SL

#1
André Arnaud de Calavon Profile Picture

André Arnaud de Cal... 663 Super User 2026 Season 1

#2
Abhilash Warrier Profile Picture

Abhilash Warrier 289 Super User 2026 Season 1

#3
Martin Dráb Profile Picture

Martin Dráb 232 Most Valuable Professional

Last 30 days Overall leaderboard

Product updates

Dynamics 365 release plans