There are many situations in which deadlocks can be created between communicating web services. However, the following rule will keep you out of trouble most of the time:
Never invoke a synchronous method on the caller to a synchronous method.
When a client invokes a synchronous method on a web service, the client will block waiting for the method to complete. If you attempt to call the client (invoke a callback) while the client is waiting for the original method to complete, then each party will be waiting for the other. This is a deadlock. The same situation could occur if a callback handler attempted to call a synchronous method on it's caller.
If you have a situation where you want to invoke a callback from a method, you can avoid deadlock by making either the method or the callback asynchronous. One simple way to make the method or callback asynchronous is to use message buffering.
To Buffer a Method or Callback
Evidence of a Deadlock
If you create a deadlock in your application, it may not be directly apparent. Typically, one of the two deadlocking requests will time out and a weblogic.transaction.internal.TimedOutException will be thrown. If you see this exception, you probably have a deadlock in your application.