Spring注解式声明事务相关问题

以下整理自己在使用Spring(3.1.1)注解式声明事务遇到的相关问题。

1、 方法的访问权限只有在public时,@Transactional才会生效。
引用

摘自 http://docs.spring.io/spring/docs/3.2.12.RELEASE/spring-framework-reference/htmlsingle/

Method visibility and @Transactional
When using proxies, you should apply the @Transactional annotation only to methods with public visibility. If you do annotate protected, private or package-visible methods with the @Transactional annotation, no error is raised, but the annotated method does not exhibit the configured transactional settings. Consider the use of AspectJ (see below) if you need to annotate non-public methods.


2、 同一个类中都声明@Transactional的方法调用,第二个方法的@Transactional不会生效。
引用

摘自 http://docs.spring.io/spring/docs/3.2.12.RELEASE/spring-framework-reference/htmlsingle/

In proxy mode (which is the default), only external method calls coming in through the proxy are intercepted. This means that self-invocation, in effect, a method within the target object calling another method of the target object, will not lead to an actual transaction at runtime even if the invoked method is marked with @Transactional.


3、 嵌套事务(子事务以REQUIRES_NEW方式)造成数据库死锁
引用

摘自 http://stackoverflow.com/questions/17747906/getting-deadlock-found-when-trying-to-get-lock-try-restarting-transaction

MySQL's InnoDB engine sports row-level locking, which can lead to deadlocks even when your code is inserting or updating a single row (specially if there are several indexes on the table being updated). Your best bet is to design the code around this in order to retry a transaction if it fails due to a deadlock. Some useful info about MySQL deadlock diagnose and possible workarounds is available here.

An interesting implementation of deadlock retry via AOP in Spring is available here. This way you just need to add the annotation to the method you want to retry in case of deadlock.


4、 在事务提交\事务回滚之后,处理一些事情。
// 在业务代码中,调用此代码
TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter(){
	// 重写afterCommit或者afterCompletion
    // 在事务提交\事务回滚之后,就会执行
});

猜你喜欢

转载自renxin-327666062-qq-com.iteye.com/blog/2163132