A user context is a user-transaction context. This means that its lifecycle is outside a database transaction, and outside the database. Its lifecycle is determined by the API user.
Any non-readonly service should be passed a user context as a parameter. The user context should be obtained from a user context factory.
Each runtime environment (standalone Java application, web application, EJB application, etc.) may have a different user context factory, since this factory may choose to hang the user context on different objects.
For example - a Java application will probably use the TlsUserContextFactory that hangs the user context on the thread local storage. A web application will most probably be using the PerInstanceUserContextFactory that hangs the user context on the current request.
The user context should always be obtained from the user context factory. To do so, simply:
UserContextFactory factory=(UserContextFactory)applicationContext.getBean("userContextFactory"); UserContext uc=factory.getUserContext();
Once you decide which user context factory is relevant for your application, you may have to define it as a bean spring. For example, to define a thread local storage user context factory:
<bean id="userContextFactory" class="net.sf.shineframework.common.tx.context.spring.TlsUserContextFactory"> <constructor-arg value="net.sf.shineframework.common.tx.context.spring.StandardUserContext" /> </bean>
Other user context factories may require different definitions.
As mentioned before you simply need to pass the user context to a non-readonly service in order to use it. However, once the service is complete, you are required to check the status of the user context.
A user context indicates the status of the last transaction. It may consist of messages (fatal, error, warning or info). And it may also show that the transaction has failed. A transaction will fail if a fatal or an error message has been added to the user context. A transaction may also fail if a warning message has been added to the user context if this is a requirement. To set the fail level of the transaction you may use the user context setFailOnWarn method.
Clearing the user context is the equivalent of ending the transaction. To clear the user context:
UserContextFactory factory=(UserContextFactory)applicationContext.getBean("userContextFactory"); factory.clearUserFactory();
Some user context factories may not require you to cleat the user context. For example - the PerInstanceUserContextFactory will automatically clear the user context as a side effect of the location it hangs it. Since this type of user context factory hangs the active user context object on the request, then when the request ends - all the objects on it end with it, and thus starting a new request automatically starts a new user transaction. However, the TlsUserContextFactory, as mentioned before, hangs the user context on the tls, which means that as long as the thread lives you are within the context of the same transaction. In some situations you may wish to clear the user context and start a new transaction in mid-thread activity.
Fortunately, most of the time you will not need to think about this at all, you will most probably be using the user context without clearing it, letting the underlying user context factory mechanisms choose when to clear it for you.
When writing a non-readonly transaction (within a service) you should require that a user context be passed as a parameter. Use the user context addMessage methods to add messages to the user context. You may also check the user transaction status in mid-transaction, and return early if it has already failed.