Does Hibernate automatically restart transactions when deadlocked?

A lot has been written in this thread:

  • MySQL transaction reload after deadlock
  • Deadlock detected while trying to get a lock; try restarting the transaction: @RetryTransaction
  • MySQL JDBC: is there an auto retry option after locking InnoDB?
  • Work with MySQL error. "Deadlock detected while trying to get a lock; try restarting the transaction
  • ... many more

I am particularly interested in the last accepted answer:

If you use InnoDB or any transactional DBMS at the row level, then it is possible that any write transaction can cause a dead end, even in completely normal situations. Large tables, large records, and long transaction blocks often increase the likelihood of locks occurring. In your situation, this is probably a combination of these.

This would mean that we can never prevent them, but only to cope with them. It's true? I wonder if you can ever prevent deadlocks on a site with 1,000 people on the Internet that cause database write operations.

A search on a topic does not yield any interesting results. Only one I found this ( http://www.coderanch.com/t/415119/ORM/databases/Deadlock-problems-Hibernate-Spring-MS ):

public class RestartTransactionAdviser implements MethodInterceptor { private static Logger log = Logger.getLogger(RestartTransactionAdviser.class); public Object invoke(MethodInvocation invocation) throws Throwable { return restart(invocation, 1); } private Object restart(MethodInvocation invocation, int attempt) throws Throwable { Object rval = null; try { rval = invocation.proceed(); } catch (Exception e) { Throwable thr = ExceptionUtils.getRootCause(e); if (thr == null) { throw e; } if (StringUtils.contains(thr.getMessage(), "deadlock") || StringUtils.contains(thr.getMessage(), "try restarting transaction") || StringUtils.contains(thr.getMessage(), "failed to resume the transaction")) { if (attempt > 300) { throw e; } int timeout = RandomUtils.nextInt(2000); log.warn("Transaction rolled back. Restarting transaction."); log.debug("Spleep for " + timeout); log.debug("Restarting transaction: invocation=[" + invocation + "], attempt=[" + attempt + "]"); Thread.sleep(timeout); attempt++; return restart(invocation, attempt); } else { throw e; } } return rval; } } 

On the other hand, I seriously doubt the quality of such a decision. Can you talk about what would be the best way to deal with dead ends? How to deal with deadlocks in banks and corporate applications?

+7
java spring mysql hibernate transactions
source share
1 answer

A Hibernate session implies a transactional entry for the first level cache. This allows you to transfer changes to the last crucial moment, thereby reducing lock capture intervals (even occurs at the isolation level READ_COMMITTED ).

This means that you need to minimize all transaction time, and I can recommend FlexyPool for such an effort. You need to make sure that all transactions are as short as possible in order to reduce blocking intervals in order to increase scalability.

A lock introduces sequential operations, and according to Amdahl's law , scalability is inversely proportional to the total portion of serial operations.

My advice is to get started with reducing transaction intervals first. Indexing will reduce query time. ORMs can generate terrible requests, so make sure your tests verify expected requests against actual ones .

A tool like p6spy is very convenient for synchronizing your requests, so make sure you use it too.

When all transactions are as short as possible and you still need more concurrency, you can move on to horizontal scalability. First, you can start with a synchronous master-slave replication strategy and redirect the read to the sub-node, while maintaining the master for write transactions.

+4
source share

All Articles