spring中同步的方法依旧插入了相同的数据

由于某些原因,我给某个方法加了同步,但是昨晚发现,这个方法依然插入了相同的数据…

Cache_-40c8217c8b06bf0c..jpg

方法简化如下:

@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Throwable.class)
public synchronized void add() {
	checkExists();
	insert();
}

懵逼了一阵子之后发现原来是spring的aop事务搞得鬼。。。 实际执行的方法应该可以简化如下:

public void addInTransaction(){
	beginTransaction();
	synchronized (service) {
		add();
	}
	commitTransaction();
}

解决方法也简单,放弃aop事务,利用PlatformTransactionManager或者TransactionTemplate将事务控制在同步方法内,或者直接将事务级别设置并行化。

如果为了省力一点,也可以这样:

@Target({ ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Sync {

}

@Component
@Aspect
@Order(value = Ordered.HIGHEST_PRECEDENCE)
public class SyncInterceptor {

	@Around("@annotation(Sync)")
	public Object around(ProceedingJoinPoint pjp) throws Throwable {
		synchronized (pjp.getTarget()) {
			return pjp.proceed();
		}
	}

}