公司做网站推广要注意什么,如何制作一个软件app,建网站学什么,wordpress 调用前言#xff1a;在 Java 开发中#xff0c;事务管理是非常重要的一环。Spring 框架提供了Transactional注解来简化事务管理的操作#xff0c;本文将深入介绍Transactional注解的用法#xff0c;并结合代码示例进行详细讨论。
1.Transactional 注解简介 Transactional注解是… 前言在 Java 开发中事务管理是非常重要的一环。Spring 框架提供了Transactional注解来简化事务管理的操作本文将深入介绍Transactional注解的用法并结合代码示例进行详细讨论。
1.Transactional 注解简介 Transactional注解是 Spring 框架中用于管理事务的关键注解之一。通过在方法或类上添加该注解Spring 会自动为被注解的方法创建一个事务并在方法执行完毕后根据执行情况提交或回滚事务。这样可以确保数据库操作的原子性保证数据的完整性。
Service
Transactional
public class UserService {Autowiredprivate UserRepository userRepository;public void updateUser(User user) {userRepository.save(user);}
}在上面的示例中Transactional注解被添加到UserService类上表示其中的方法将在事务管理下执行。
2.Transactional 失效的情况 尽管Transactional注解可以很好地管理事务但在某些情况下它可能会失效导致事务无法正常工作。以下是一些可能导致Transactional注解失效的情况
2.1 自调用问题 如果在同一个类中一个带有Transactional注解的方法直接调用另一个带有Transactional注解的方法事务可能不会起作用因为 Spring 默认使用代理机制来管理事务自调用会绕过代理对象导致事务失效。
Service
Transactional
public class UserService {Autowiredprivate UserRepository userRepository;public void updateUser(User user) {saveUser(user); // 这里的调用会绕过代理对象事务失效}Transactionalpublic void saveUser(User user) {userRepository.save(user);}
}2.2 异常捕获问题 当方法内部捕获了异常并不再抛出时事务可能会失效。Spring 默认只会对未捕获的异常进行事务回滚如果异常被捕获并在方法内部处理事务可能无法正常回滚。
Service
Transactional
public class UserService {Autowiredprivate UserRepository userRepository;public void updateUser(User user) {try {userRepository.save(user);} catch (Exception e) {// 异常被捕获事务可能无法回滚}}
}2.3 抛出非运行时异常 异常虽然抛出了但是抛出的是非RuntimeException类型的异常依旧不会生效。
Transactional
public void deleteUser() throws MyException{userMapper.deleteUserA();try {int i 1 / 0;userMapper.deleteUserB();} catch (Exception e) {throw new MyException();}
}如果指定了回滚异常类型为Exception那么就可以回滚非RuntimeException类型异常了。
Transactional(rollbackFor Exception.class)2.4 新开启一个线程 如下的方式deleteUserA()也不会回滚因为spring实现事务的原理是通过ThreadLocal把数据库连接绑定到当前线程中新开启一个线程获取到的连接就不是同一个了
Transactional
public void deleteUser() throws MyException{userMapper.deleteUserA();try {//休眠1秒保证deleteUserA先执行Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}new Thread(() - {int i 1/0;userMapper.deleteUserB();}).start();
}2.5 非public方法 如果Transactional注解标记的方法是非public的那么事务将失效。这是因为Spring默认使用基于代理的AOP来实现事务而基于代理的AOP只能拦截public方法。
Transactional
private void doSomething() {// 执行业务逻辑
}
2.6 未被Spring容器管理 如果Transactional注解标记的方法所在的类没有被Spring容器管理那么事务将失效。这是因为Spring只会对由Spring容器管理的Bean进行事务管理。 public class UserService {Autowiredprivate UserRepository userRepository;Transactionalpublic void updateUser(User user) {userRepository.save(user);}
}2.7 数据库本身不支持 数据库本身不支持事务管理。mysql数据库必须设置数据库引擎为InnoDB。
2.8 事务传播属性设置错误 注意传播属性的设置比如设置了PROPAGATION_NOT_SUPPORIED以非事务的方式执行如果当前有事务则把当前事务挂起。
3. 解决方案 针对上述问题我们可以采取一些解决方案来确保Transactional注解的有效性。比如避免在同一个类中使用自调用的方式或者在捕获异常后手动抛出以触发事务回滚。
4. 总结 通过Transactional注解我们可以轻松管理事务确保数据库操作的一致性。然而在编写代码时需要注意可能导致注解失效的情况避免出现意外的事务行为。持续学习和实践是掌握事务管理的关键希望本文对您有所帮助。