Spring 使用事务操作时的细节

Spring 使用事务操作时的细节

之前用事务用的不是很多(因为都是微服务框架,一个业务操作都是跨应用的),所以一直对事务没有认真对待,现在发现这里面还有这么多门道。

1.事务和分布式锁同时使用,一定要注意彼此的作用域

事务在数据库中是有隔离性的,mysql默认的隔离性是RR,不同事务是看不到其他事务未提交的操作的。
所以在同时使用分布式锁和事务注解时,一定要注意作用域,如果是以下场景,分布式锁就根本没有起到相应的作用,直接被忽略掉了。这个问题超级坑,很难查,会怀疑人生的。
在这里插入图片描述

2.this自调用事务失效

事务失效的场景有很多,也有很多这样的博客来总结,这些我就不贴了,只说一下对于比较常见的this自调用怎么来让事务生效。
由于Spring依靠代理来实现事务,所以要先要获取到当前类的代理对象(直接this调用是不经过代理对象的),Spring也为我们这种操作提前准备了相关方法,用于获取当前类代理对象。

Service currentProxy = (Service) AopContext.currentProxy();

但是要在启动类上增加注解,用于开启这种功能,否则会报错。

@EnableAspectJAutoProxy(exposeProxy = true)

3.private方法事务失效

这种方法的解决,我建议在private方法中,手动开启事务最快捷和简单,当然也有其他的方法,不过这种场景毕竟在少数。
由于事务的相关类都在Spring的容器中,其实手动开启事务并不是很麻烦。
首先,注入事务管理器

	@Autowired
	private PlatformTransactionManager platformTransactionManager;

然后在代码中,声明一下事务的隔离级别,开启事务进行提交和回滚就好了。

		DefaultTransactionDefinition transactionDefinition = new DefaultTransactionDefinition();
		transactionDefinition.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);

		TransactionStatus transactionStatus = platformTransactionManager.getTransaction(transactionDefinition);
		try {
    
    
			// xxx
			platformTransactionManager.commit(transactionStatus);
		} finally {
    
    
			platformTransactionManager.rollback(transactionStatus);
		}

猜你喜欢

转载自blog.csdn.net/lvqinglou/article/details/115465744