hibernate Lock wait timeout exceeded;

前端 未结 1 751
忘掉有多难
忘掉有多难 2021-02-06 00:34

I am using Hibernate, trying to simulate 2 concurrent update to the same row in database.

Edit: I moved em1.getTransaction().commit to be right after em1.flush(); I am n

1条回答
  •  太阳男子
    2021-02-06 01:15

    Well, you're trying to get into a deadlock and you're succeeding :-)

    1. Transaction1 starts, updates (and locks) row with your entity.
    2. Transaction2 tries to do the same but can't because the row is still locked. So it waits (and waits, and waits) until timeout is exceeded

    Real life simulation would have 1st and 2nd entity manager plus appropriate updates / transactions in separate threads. That way you'd have:

    1. Transaction1 starts, updates (and locks) row with your entity.
    2. Transaction2 tries to do the same but can't because the row is still locked. So it waits (and waits, and waits) ...
    3. Meanwhile Transaction1 is committed and lock is released
    4. Transaction2 can now proceed

    Note that at that point (#4 above) you'd be overwriting changes made by Transaction1. Hibernate can use optimistic locking as well as pessimistic locking to prevent that from happening.

    Update (based on comment):

    If the entity is versioned, Transaction2 (#4 above) will fail. However, your code as posted does not get to that point because Transaction2 can't obtain the lock as explained above. If you want to specifically test that optimistic version control is working you can do the following:

    1. Obtain em1, start transaction, get your entity, commit transaction, close em1.
    2. Obtain em2, start transaction, get your entity, update your entity, commit transaction, close em2.
    3. Obtain em3, start transaction, attempt to update entity you've loaded in step 1 - test should fail here.

    0 讨论(0)
提交回复
热议问题