001//
002// Name
003//  $RCSfile: Asynchronous.java,v $
004// 
005// Copyright
006//  Copyright 2010-2015 Cloud Software Group, Inc. ALL RIGHTS RESERVED.
007//  Cloud Software Group, Inc. Confidential Information
008//
009// History
010//  $Revision: 1.1.2.5 $ $Date: 2015/01/27 03:23:59 $
011//
012package com.kabira.platform.annotation;
013
014import com.kabira.platform.Transaction;
015
016import java.lang.annotation.Documented;
017import java.lang.annotation.ElementType;
018import java.lang.annotation.Inherited;
019import java.lang.annotation.Retention;
020import java.lang.annotation.RetentionPolicy;
021import java.lang.annotation.Target;
022
023/**
024 * Annotation to indicate whether a method should be executed
025 * asynchronously.
026 * <p>
027 * The default behavior is to execute a Managed object method synchronously
028 * within the calling transaction. When annotated as &#64;Asynchronous, a method
029 * runs asynchronously in a separate transaction. A new transaction is
030 * transparently started for the method, and deadlocks are automatically
031 * retried.
032 * <p>
033 * If the work done in an asynchronous method is supposed to be rolled
034 * back, the method should throw a {@link
035 * com.kabira.platform.Transaction.Rollback} exception.
036 * <p>
037 * A method annotated as &#64;Asynchronous must have a void return and
038 * parameters are restricted to those types supported for Managed objects.  
039 * <p>
040 * The {@link com.kabira.platform.Transaction.Result} of an asynchronous
041 * method is not available to an application. Applications that need to
042 * keep track of this need to implement a separate non-transactional
043 * mechanism to track this.
044 * <p>
045 * Execution of asynchronous methods have the following behavior:
046 * <ul>
047 * <li> The method is executed and the enclosed transaction started after
048 * the calling transaction commits.
049 * <li> If the calling transaction is rolled back, the method is not
050 * executed.
051 * <li> The runtime guarantees that the method executes to completion
052 * once and only once.
053 * <li> Multiple calls to an asynchronous method on a same Managed object
054 * instance are guaranteed to execute in the same order. Given:
055 *<pre>&#64;Managed
056class MyClass
057{
058    &#64;Asynchronous
059    void asyncOp(int val);
060}
061new Transaction()
062{
063    &#64;Override
064    public void run()
065    {
066        ...
067        myObj.asyncOp(1);
068        myObj.asyncOp(2);
069    }
070}.execute();</pre>
071 * The runtime insures that asyncOp() is called with val==1 first. 
072 * Execution of asynchronous methods on different instances have no
073 * order guarantees.
074 * </ul>
075 * <p>
076 * It is important to note that execution of an asynchronous method and
077 * its associated transaction only happen after the calling transaction
078 * commits, <b>it is not executed</b> if the calling transaction is
079 * rolled back for any reason.
080 * <p>
081 * If the &#64;Asynchronous annotation is used on a method for a class that
082 * isn't &#64;Managed, the annotation is ignored.
083 * @see com.kabira.platform.annotation.Managed
084 * @see com.kabira.platform.Transaction
085 * @see com.kabira.platform.Transaction.Rollback
086 */
087@Documented
088@Inherited
089@Retention(RetentionPolicy.RUNTIME)
090@Target(ElementType.METHOD)
091public @interface Asynchronous
092{
093    /**
094      * Define the transaction isolation level used when running
095      * this transaction.
096      @return IsolationLevel
097      */
098    Transaction.IsolationLevel isolationLevel()
099                        default Transaction.IsolationLevel.SERIALIZABLE;
100}