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?
java spring mysql hibernate transactions
Vojtěch
source share