[[transactions-and-errors]]
= Transactions and Errors

:Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at. http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR  CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
:page-partial:

In Apache Isis, every interaction (action invocation or property edit) is automatically wrapped in a transaction, and any repository query automatically does a flush before hand.

What that means is that there's no need to explicitly start or commit transactions in Apache Isis; this will be done for you.
Indeed, if you do try to manage transactions (eg by reaching into the JDO `PersistenceManager` exposed by the xref:refguide:persistence:index/jdo/applib/services/JdoSupportService.adoc[JdoSupportService] domain service, then you are likely to confuse the framework and get a stack trace for your trouble.

However, you can complete a given transaction and start a new one.
This is sometimes useful if writing a xref:testing:fixtures:about.adoc[fixture script] which is going to perform some sort of bulk migration of data from an old system.
For this use case, use the xref:refguide:applib:index/services/xactn/TransactionService.adoc[TransactionService].

For example:

[source,java]
----
public class SomeLongRunningFixtureScript extends FixtureScript {

    protected void execute(final ExecutionContext executionContext) {
        // do some work
        transactionService.nextTransaction();
        // do some work
        transactionService.nextTransaction();
        // do yet more work
    }

    @javax.inject.Inject
    TransactionService transactionService;
}
----


== Raise message in the UI

The framework provides the xref:refguide:applib:index/services/message/MessageService.adoc[MessageService] as a means to return an out-of-band message to the end-user.
In the xref:vw:ROOT:about.adoc[Web UI (Wicket viewer)] these are shown as "toast" pop-ups; the
xref:vro:ROOT:about.adoc[REST API (Restful Objects viewer)] returns an HTTP header.

The `UserService` provides three APIs, for different:

* `informUser()` - an informational message.
In the Wicket viewer these are short-lived pop-ups that disappear after a short time.
* `warnUser()` - a warning.
In the Wicket viewer these do not auto-close; they must be acknowledged.
* `raiseError()` - an error.
In the Wicket viewer these do not auto-close; they must be acknowledged.

Each pop-up has a different background colour indicating its severity.

None of these messages/errors has any influence on the transaction; any changes to objects will be committed.

== Aborting transactions

If you want to abort Apache Isis' transaction, this can be done by throwing an exception.
The exception message is displayed to the user on the error page (if xref:vw:ROOT:about.adoc[Web UI (Wicket viewer)]) or a 500 status error code (if the
xref:vro:ROOT:about.adoc[Restful Objects] viewer).

If the exception thrown is because of an unexpected error (eg a `NullPointerException` in the domain app itself), then the error page will include a stack trace.
If however you want to indicate that the exception is in some sense "expected", then throw a `RecoverableException` (or any subclass, eg `ApplicationException`); the stack trace will then be suppressed from the error page.

Another way in which exceptions might be considered "expected" could be as the result of attempting to persist an object which then violates some type of database constraint.
Even if the domain application checks beforehand, it could be that another user operating on the object at the same moment of time might result in the conflict.

To handle this the xref:refguide:applib:index/services/exceprecog/ExceptionRecognizerService.adoc[ExceptionRecognizer] SPI can be used.
The framework provides a number of implementations out-of-the-box; whenever an exception is thrown it is passed to each known recognizer implementation to see if it recognizes the exception and can return a user-meaningful error message.
For example, `ExceptionRecognizerForSQLIntegrityConstraintViolationUniqueOrIndexException` checks if the exception inherits from `java.sql.SQLIntegrityConstraintViolationException`, and if so, constructs a suitable message.

