users@ejb-spec.java.net

[ejb-spec users] [jsr345-experts] Re: Transaction timeout

From: Carlo de Wolf <cdewolf_at_redhat.com>
Date: Mon, 12 Dec 2011 11:58:23 +0100

I've raised http://java.net/jira/browse/EJB_SPEC-46 using the annotation
you provided.

Let's dig into the edge case:

@Stateless class FooBean {
    @EJB OtherBean other;

    @TransactionAttribute(NEVER)
    @TransactionTimeout(30)
    public void doSomething() {
       other.doSomethingElse();
    }
}

@Stateless class OtherBean {
    @TransactionAttribute(REQUIRED) // REQUIRES_NEW
    public void doSomethingElse() {
       assert currentTransactionTimeout() == 30;
    }
}

Does it blend?

I would say yes. The transaction timeout is set on the current thread
before FooBean.doSomething.

Note that however we do this it has implications for remote view
invocations.

Carlo

On 12/09/2011 04:29 PM, David Blevins wrote:
> It's a good concept.
>
> The fact that many @TransactionAttributes can effectively affect a single transaction seems to lead me to the conclusion that the timeout should be a different annotation. Otherwise I suspect there will be several frustrated people who can't figure out why the timeout doesn't work when they put it on SUPPORTS or worse REQUIRED in situations where that particular method didn't start the transaction.
>
> Perhaps @TransactionTimeout to be consistent with @StatefulTimeout and @AccessTimeout. We could have put the stateful timeout data on @Stateful. As well we could have put the access timeout info on @Lock. We didn't, so my vote would be for consistency.
>
> @Target({METHOD, TYPE})
> @Retention(RUNTIME)
> public @interface TransactionTimeout {
> long timeout() default -1L;
> TimeUnit unit() default TimeUnit.SECONDS;
> }
>
>
> What I wonder is that it clearly only would work 100% of the time on REQUIRES_NEW and sometimes on REQUIRED. We'll definitely have to document that, but I wonder if we might want to be a bit strict about it.
>
> Something like this is a little loose, but workable:
>
> @Stateless
> @TransactionTimeout(30)
> public class FooBean {
>
> @TransactionAttribute(REQUIRES_NEW)
> public void doSomething() {}
>
> @TransactionAttribute(NEVER)
> public void doSomething() {}
> }
>
> This is flat out wrong:
>
> @Stateless
> public class FooBean {
>
> @TransactionAttribute(REQUIRES_NEW)
> @TransactionTimeout(30)
> public void doSomething() {}
>
> @TransactionAttribute(NEVER)
> @TransactionTimeout(30)
> public void doSomething() {}
> }
>
> Not sure what tact is the best to discourage that blatant misuse.
>
>
> -David
>
>
> On Dec 9, 2011, at 3:35 AM, Carlo de Wolf wrote:
>
>> Given the functionality of a transaction manager to set the transaction timeout [1]. I would like to expose this feature in a spec defined manner.
>>
>> How about the following annotation:
>>
>> @Target({METHOD, TYPE})
>> @Retention(RUNTIME)
>> public @interface TransactionAttribute {
>> TransactionAttributeType value() default TransactionAttributeType.REQUIRED;
>> long timeout() default -1L;
>> TimeUnit unit() default TimeUnit.SECONDS;
>> }
>>
>> Where -1 means unspecified.
>>
>> And the following descriptor fragment:
>>
>> <ejb-jar version="3.2">
>> <assembly-descriptor>
>> <container-transaction>
>> <method>
>> <ejb-name>A</ejb-name>
>> <method-name>*</method-name>
>> </method>
>> <trans-attribute>RequiresNew</trans-attribute>
>> <trans-timeout>
>> <timeout>10</timeout>
>> <unit>Seconds</unit>
>> </trans-timeout>
>> </container-transaction>
>> </assembly-descriptor>
>> </ejb-jar>
>>
>> What do you guys think?
>>
>> Carlo
>>
>> [1] http://docs.oracle.com/javaee/6/api/javax/transaction/TransactionManager.html#setTransactionTimeout%28int%29
>>
>> PS. Since people are going to dig, we discussed changing transaction attributes on Oct 17th 2007.