I’m a strong believer that the internal architecture of your application, and the means by which client’s communicate with it, are two orthogonal issues. You wouldn’t want to have to change the internals of your application, just because you need to change the way clients invoke your service.
We think you should be able to develop your applications using a common Transactions API. You should then be able to invoke remote services over whatever transport is appropriate and automatically have the transaction distributed. Furthermore, you shouldn’t be restricted to having all participants use the same transport.
There really is only one option for a Java “common Transactions API” - it’s JTA. JTA is well supported in Java EE application servers and it is well understood by developers. Furthermore, there are many applications out there already using JTA.
This is what we are moving towards with each milestone release of Narayana 5.0.0. With milestone two we made it very simple for a pure JTA client to invoke a JTA application over Web Services in a distributed transaction. Take a look at the following example:
Client
@Stateless
public class OrderClient {
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public void orderItem(String item, String address, double amount) {
AccountService as = //Lookup AccountService WS client
WarehouseService ws = //Lookup WarehouseService WS client
ws.shipItem(item, address);
as.invoiceCustomer(address, amount);
}
}
public class OrderClient {
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public void orderItem(String item, String address, double amount) {
AccountService as = //Lookup AccountService WS client
WarehouseService ws = //Lookup WarehouseService WS client
ws.shipItem(item, address);
as.invoiceCustomer(address, amount);
}
}
Here the client is using a regular Stateless Session Bean. The method ‘orderItem’ is invoked in a JTA transaction that is committed if the method succeeds and rolled back if it fails.
The calls to the Warehouse and Account services automatically use WS-AT to distribute the JTA transaction. The middleware knows to do this because a JTA transaction was present when the Web Service call was invoked.
Transaction propagation can be configured, but that’s the subject of another blog post (stay tuned).
Service
@Transactional //Currently required, will be removed soon https://issues.jboss.org/browse/JBTM-1468
@Stateless
//JAX-WS annotations omitted for brevity
public class WarehouseServiceImpl implements WarehouseService {
@PersistenceContext
protected EntityManager em;
@WebMethod
public void shipItem(String item, String address) {
// Use the Entity Manager to
// add an item and shipping address to DB
}
}
@Stateless
//JAX-WS annotations omitted for brevity
public class WarehouseServiceImpl implements WarehouseService {
@PersistenceContext
protected EntityManager em;
@WebMethod
public void shipItem(String item, String address) {
// Use the Entity Manager to
// add an item and shipping address to DB
}
}
No comments:
Post a Comment