网站建设课程设计报告图文,泉州企业网站建设,做旅游攻略去什么网站,宿州市建设局网站Spring事务失效的几种情况
1、未被Spring管理的类中的方法 这种情况是指#xff1a;没有在类上添加Service、Repository、Component等注解将类交由Spring管理#xff0c;然后该类中还有加上了Transactional注解 例如#xff1a;
Service //如果没有添加Service这个注解…Spring事务失效的几种情况
1、未被Spring管理的类中的方法 这种情况是指没有在类上添加Service、Repository、Component等注解将类交由Spring管理然后该类中还有加上了Transactional注解 例如
Service //如果没有添加Service这个注解就是一种失效的情况
public class MyService {Transactionalpublic void myTransactionalMethod() {// 事务管理的代码}
}2、未正确配置事务管理器
在Spring Boot中通常会自动配置事务管理器。然而如果你手动配置了数据源或事务管理器并且配置不正确事务可能会失效。确保你的DataSource和PlatformTransactionManager配置正确 这里是它的一些错误情况 数据源配置错误 确保数据源的驱动类、连接URL、用户名和密码等配置是正确的。 事务管理器配置错误 确保事务管理器的配置正确并且它引用了正确的实体管理器工厂。 实体管理器工厂配置错误 确保实体管理器工厂的配置正确包括数据源的引用、实体类的扫描路径等。 未加入适当的数据库依赖 确保项目的依赖中包含了正确的数据库驱动依赖。 3、异常被捕获而不重新抛出 Spring事务默认只对未捕获的运行时异常进行回滚。如果在事务内捕获了异常并没有重新抛出事务可能不会回滚。 看如下的代码这个哪里有问题呢我们该如何来修改它 Transactional
public void myTransactionalMethod() {try {// 可能会抛出异常的代码// ...} catch (Exception e) {// 异常被捕获但没有重新抛出// 可能导致事务不回滚log.error(An error occurred: {}, e.getMessage());}
}在上述代码中如果在try块中的代码抛出了异常但在catch块中没有重新抛出该异常那么事务可能不会回滚。因为Spring默认只回滚未捕获的运行时异常。为了确保事务能够正常回滚应该在catch块中将异常重新抛出或采取其他适当的措施。 下面是它修改之后的代码 Transactional
public void myTransactionalMethod() {try {// 可能会抛出异常的代码// ...} catch (Exception e) {// 将异常重新抛出throw e;}
}4、自调用问题 这个就是一般最容易出现的问题了个人感觉 就是在同一个类中直接调用了另一个加上了Transactional注解的方法使Spring可能无法截获这个调用因为调用并没有经过代理对象所以事务失效了。 就是下面例子这种情况 Service
public class MyService {Transactionalpublic void methodA() {// 一些数据库操作}public void methodB() {// 一些逻辑操作methodA(); // 在同一个类中直接调用methodA}
}在这个例子中methodB在同一个类中直接调用了methodA。Spring的AOP代理没有介入即没有生成代理对象所以methodA可能就受不到Transactional注解的影响。 那如何来解决这种情况呢 解决方法 1、使用代理对象调用方法A通过GPT了解的 2、使用AopContext.currentProxy()获取当前代理对象黑马视频中学的 方法一 使用代理对象调用方法A
Service
public class MyService {Autowiredprivate MyService self; // 自动注入当前类的实例Transactionalpublic void methodB() {// 通过代理对象调用methodAself.methodA();}public void methodA() {// 一些数据库操作}
}方法二使用AopContext.currentProxy()获取当前代理对象
//使用前提需要在SpringBoot启动类上加上EnableAspectJAutoProxy(exposeProxy true)
//该注解目的是暴露代理对象如果没有暴露我们是拿不到代理对象的
Service
public class MyService {Transactionalpublic void methodB() {// 获取当前代理对象MyService proxy (MyService) AopContext.currentProxy();// 通过代理对象调用methodAproxy.methodA();}public void methodA() {// 一些数据库操作}
}更多了解
百度安全验证
https://www.cnblogs.com/xiaowangbangzhu/p/17143288.html