The previous change was probably not enough, as MySQL uses locks at the row level, not at table level.
Suppose that a purge transaction A first gets hold on a large number of session_attribute rows for deleting them, then tries to do the same for a large number of rows in the session session. At the same time, another transaction B could well have already locked one of these session rows, and then tries to access a session_attribute row already locked by transaction A. We again have a deadlock, at the row level.