English 中文(简体)
How to restart transactions on deadlock/lock-timeout in Spring?
原标题:

What is the best practice on implementing a transaction restart upon deadlock or lock timeout exceptions when using Spring (specifically the Spring recommended approach: declarative transactions) ?

Thanks,

Asaf

问题回答

I feel like Spring itself should have a good answer to this question (in the form of documentation, at the least, or a retry interceptor of some sort). Alas, it does not.

Probably the best way to handle retries (if you want to continue being "declarative" about things) is to write your own interceptor implementation that will automatically retry the transaction a configured number of times. For starters, study Spring s TransactionInterceptor, which manages begin/rollback/commit behavior for declarative transactions. If you re using Hibernate, note how it handles Hibernate session binding/unbinding to the current Thread.

Things to watch out for if you re using Hibernate:

  • Your "retry interceptor" should be sure to unbind any preexisting thread-bound Hibernate session and rebind a new one. Once an exception (e.g., deadlock) is thrown from within Hibernate/JDBC code the corresponding Hibernate session is poisoned and needs to be discarded. (session.clear() is not sufficient.)
  • Be careful if your transactional service methods use Hibernate session objects as method parameters. On retry, when you reset your Hibernate session, these objects will be detached. You ll need to reattach them if the service method assumes they are attached (e.g., if they use lazy loaded properties that get accessed in the service method, or if you try to save them, etc.) In general, it s better if you don t use Hibernate objects as parameters to transactional service methods.
  • You ll be implementing MethodInterceptor.invoke() -- the MethodInvocation instance that gets passed in to this may be stateful; you may need to clone it before using it in the interceptor.

I recommend using the class org.springframework.retry.interceptor.RetryOperationsInterceptor from the spring retry project, configured like this:

<aop:config>
    <aop:pointcut id="transactional" expression="execution(* com...*Service.remoteCall(..))" />
    <aop:advisor pointcut-ref="transactional" advice-ref="retryAdvice" order="-1"/>
</aop:config>

<bean id="retryAdvice" class="org.springframework.retry.interceptor.RetryOperationsInterceptor"/>

But if you still want to implement it by yourself, the example of AOP from spring documentation is a good start.

There is no universal answer because it depends on application specifics. For example you may want to perform automatic transacted operation restart or notify the user about operation failure and ask for explicit retry confirmation etc.

I d use AOP in case of automatic restart scenario.

I had the same question several years ago and ended up writing my own solution as an AOP aspect, which ends up looking like this in your code:

  @RetryTransaction
  @Transactional
  public void doSomething() {
      ....
  }




相关问题
Spring Properties File

Hi have this j2ee web application developed using spring framework. I have a problem with rendering mnessages in nihongo characters from the properties file. I tried converting the file to ascii using ...

Logging a global ID in multiple components

I have a system which contains multiple applications connected together using JMS and Spring Integration. Messages get sent along a chain of applications. [App A] -> [App B] -> [App C] We set a ...

Java Library Size

If I m given two Java Libraries in Jar format, 1 having no bells and whistles, and the other having lots of them that will mostly go unused.... my question is: How will the larger, mostly unused ...

How to get the Array Class for a given Class in Java?

I have a Class variable that holds a certain type and I need to get a variable that holds the corresponding array class. The best I could come up with is this: Class arrayOfFooClass = java.lang....

SQLite , Derby vs file system

I m working on a Java desktop application that reads and writes from/to different files. I think a better solution would be to replace the file system by a SQLite database. How hard is it to migrate ...

热门标签