
session_transaction(++Session, +Goal)

   executes Goal as a database transaction.

Arguments
   Session             A session handle
   Goal                Prolog goal that implements a database update.

Type
   library(dbi)

Description

 This executes Goal as a database transaction. This predicate is only useful
 if the database supports transactions (i.e. changes are local until committed).
 If Goal succeeds session_transaction/2  commits the update, cuts any
 alternative solutions to Goal and succeeds itself.

 If Goal fails or causes a database error, session_transaction/2 fails and
 rolls back any changes done to the database.

 If Goal aborts, the update is rolled back, and session_transaction/2 aborts.

 MySQL specific note: transactions are supported for transactional tables only
 (i.e. stored with a storage engine with transaction-safe capabilities).

 Calls of this predicate can be nested, but only the outermost transaction 
 is real. All the inner transactions are simply equivalent to call(Goal).
 This way it is possible to write a call to session_transaction/2, into 
 some code that implements a simple update, but then to include that simple 
 update into a larger transaction.

 Similarly session_commit/1 and session_rollback/1 alter their behaviour so
 that they can be used within a transaction.

 Transactions are local to one session so there is no way to safely make an 
 update relating to several sessions.

Modules
   This predicate is sensitive to its module context (tool predicate, see @/2).

Exceptions
     5 --- Session is not a valid session handle
   abort --- session_rollback/1 called within Goal

Examples
   
transfer(Session, Amount,FromAccount,ToAccount) :-
     session_transaction(Session, 
         transfer_(Session,Amount,FromAccount,ToAccount)
     ).

% note '?' in SQL in the syntax MySQL uses for placeholders. This may be
% different in other DBMS
transfer_(Session, Amount, FromAccount, ToAccount) :-
    SQL = "update accounts set balance = balance + ? \
                                             where id = ?",
    Deduct is - Amount,
    session_sql_prepare(Session,incbal(1.0,12),SQL,1,Update),
    cursor_next_execute(Update,incbal(Deduct,FromAccount)),
    cursor_next_execute(Update,incbal(Amount,ToAccount)).


See Also
   session_rollback / 1, session_commit / 1
