The following sections describe some of the most common deadlock scenarios and suggestions on how to avoid them.
The following exception displays as a result:
com.ibm.websphere.objectgrid.plugins.LockDeadlockException: Message
This
message represents the string that is passed as a parameter when the
exception is created and thrown.Description: When a transaction or client asks for a lock to be granted for a specific map entry, the request often waits for the current client to release the lock before the request is submitted. If the lock request remains idle for an extended time, and a lock is never granted, LockTimeoutException exception is created to prevent a deadlock, which is described in more detail in the following section. You are more likely to see this exception when you configure a pessimistic locking strategy, because the lock never releases until the transaction commits.
Retrieve more details:
try {
...
}
catch (LockTimeoutException lte) {
System.out.println(lte.getLockRequestQueueDetails());
}
try {
...
}
catch (ObjectGridException oe) {
Throwable Root = findRootCause( oe );
if (Root instanceof LockTimeoutException) {
LockTimeoutException lte = (LockTimeoutException)Root;
System.out.println(lte.getLockRequestQueueDetails());
}
}
Solution: A LockTimeoutException exception prevents possible deadlocks in your application. An exception of this type results when the exception waits a set amount of time. You can set the amount of time that the exception waits by setting the lock timeout value. If a deadlock does not actually exist in your application, adjust the lock timeout to avoid the LockTimeoutException.
Description: The following scenarios describe how deadlocks can occur when a single key is accessed with an S lock and later updated. When this action occurs from two transactions simultaneously, a deadlock occurs.
Thread 1 | Thread 2 | ||
---|---|---|---|
1 | Start transaction | Start transaction | Each thread establishes an independent transaction. |
2 | get key1 | get key1 | S lock granted to both transactions for key1. |
3 |
|
No U lock. Update performed in transactional cache. | |
4 |
|
No U lock. Update performed in the transactional cache | |
5 | Commit transaction | Blocked: The S lock for key1 cannot be upgraded to an X lock because Thread 2 has an S lock. | |
6 | Commit transaction | Deadlock: The S lock for key1 cannot be upgraded to an X lock because T1 has an S lock. |
Thread 1 | Thread 2 | ||
---|---|---|---|
1 | Start transaction | Start transaction | Each thread establishes an independent transaction. |
2 | get key1 | S lock granted for key1 | |
3 |
|
get key1 | S lock is upgraded to a U lock for key1. |
4 | get key1 | S lock granted for key1. | |
5 |
|
Blocked: T1 already has U lock. | |
6 | Commit transaction | Deadlock: The U lock for key1 cannot be upgraded. | |
7 | Commit transaction | Deadlock: The S lock for key1 cannot be upgraded. |
Thread 1 | Thread 2 | ||
---|---|---|---|
1 | Start transaction | Start transaction | Each thread establishes an independent transaction |
2 | get key1 | S lock granted for key1. | |
3 |
|
S lock is upgraded to a U lock for key1 | |
4 | get key1 | S lock is granted for key1. | |
5 |
|
Blocked: Thread 1 already has a U lock. | |
6 | Commit transaction | Deadlock: The U lock for key1 cannot be upgraded to an X lock because Thread 2 has an S lock. |
Thread 1 | Thread 2 | ||
---|---|---|---|
1 | Start transaction | Start transaction | Each thread establishes an independent transaction. |
2 |
|
U lock granted to thread 1 for key1. | |
3 |
|
U lock request is blocked. | |
4 |
|
<blocked> | |
5 | Commit transaction | <blocked> | The U lock for key1 can be successfully upgraded to an X lock. |
6 | <released> | The U lock is finally granted to key1 for thread 2. | |
7 |
|
U lock granted to thread 2 for key2. | |
8 | Commit transaction | The U lock for key1 can successfully be upgraded to an X lock. |
Description: This scenario describes what happens if two transactions attempt to update the same entry directly and hold S locks to other entries.
Thread 1 | Thread 2 | ||
---|---|---|---|
1 | Start transaction | Start transaction | Each thread establishes an independent transaction. |
2 | get key1 | get key1 | S lock granted to both transactions for key1. |
3 | get key2 | get key2 | S lock granted to both transactions for key2. |
4 |
|
No U lock. Update performed in transactional cache. | |
5 |
|
No U lock. Update performed in transactional cache. | |
6. | Commit transaction | Blocked: The S lock for key 1 cannot be upgraded to an X lock because thread 2 has an S lock. | |
7 | Commit transaction | Deadlock: The S lock for key 2 cannot be upgraded because thread 1 has an S lock. |
Thread 1 | Thread 2 | ||
---|---|---|---|
1 | Start transaction | Start transaction | Each thread establishes an independent transaction. |
2 |
|
U lock granted to transaction T1 for key1. | |
3 |
|
U lock request is blocked. | |
4 | get key2 | <blocked> | S lock granted for T1 for key2. |
5 |
|
<blocked> | |
6 | Commit transaction | <blocked> | The U lock for key1 can be successfully upgraded to an X lock. |
7 | <released> | The U lock is finally granted to key1 for T2 | |
8 | get key2 | S lock granted to T2 for key2. | |
9 |
|
U lock granted to T2 for key2. | |
10 | Commit transaction | The U lock for key1 can be successfully upgraded to an X lock. |
Thread 1 | Thread 2 | ||
---|---|---|---|
1 | Start transaction | Start transaction | Each thread establishes an independent transaction. |
2 |
|
|
U locks successfully granted for key1 and key2. |
3 | get key2 | get key1 | S lock granted for key1 and key2. |
4 |
|
|
|
5 | Commit transaction | The U lock cannot be upgraded to an X lock because T2 has an S lock. | |
6 | Commit transaction | The U lock cannot be upgraded to an X lock because T1 has an S lock. |