何时需要使用事务
- 业务逻辑需要保证原子性:当业务逻辑需要保证操作的一致性和原子性时,需要使用事务。例如,在进行数据插入或更新时,需要保证数据的完整性,避免因为中途出现异常而导致数据不一致。
- 多个操作需要作为一个整体进行提交或回滚:当多个操作需要作为一个整体进行提交或回滚时,需要使用事务。例如,在购买商品的流程中,需要扣除库存、记录订单和支付等多个操作,这些操作必须在同一个事务中完成,以保证数据的一致性。
- 多个数据库操作需要保持一致性:当涉及多个数据库操作时,需要使用事务来保证操作的一致性。例如,在多个数据库表之间进行关联查询或更新时,需要使用事务来确保数据的正确性和一致性。
- 数据库锁定:当需要对数据库进行锁定操作时,需要使用事务。例如,在进行高并发操作时需要使用悲观锁或乐观锁,通过事务来确保数据的一致性和有效性。
使用事务坏处
- 性能影响:事务需要维护日志、加锁等机制来保证数据的一致性,这会带来一定的性能开销。特别是在高并发场景下,事务对数据库的资源竞争可能会导致性能下降。
- 锁竞争和死锁:事务的加锁机制可能导致多个事务之间的锁竞争,从而降低并发性能。此外,如果事务嵌套、锁的粒度过大或者应用不当,可能会导致死锁的问题。
- 数据一致性延迟:事务需要等待提交或回滚才能将数据永久保存或放弃,这可能导致一些操作的结果不能立即对外部可见,造成数据一致性的延迟。
- 代码复杂性:使用事务需要在代码中显式地标注和管理事务,这增加了代码的复杂性和维护成本。特别是在大型项目中,事务的管理可能变得很繁琐。
- 数据库资源占用:事务涉及到数据库的锁定、写日志等操作,会占用更多的数据库资源,特别是在长事务或者大事务的情况下,可能会影响到其他事务的执行和数据库的性能。
因此,在使用事务时需要权衡利弊,根据实际需求和场景来判断是否需要使用事务。对于一些简单的操作或并发要求不高的场景,可以考虑不使用事务来提升性能。而对于涉及到数据一致性和完整性要求较高的复杂操作,使用事务是必要的。在使用事务时,也需要合理设计事务的粒度和隔离级别,以及避免长事务和过多锁定等问题。
事务具体使用步骤
1、在主类加注解@EnableTransactionManagement
2、在类或者方法加注解@Transactional
注意事务回滚自动完成rollbackFork可以注解需要回滚的错误类型
常见的业务需要使用事务
- 转账操作:当进行资金转账时,如果扣款成功但收款失败,或者扣款和收款都成功但是更新账户余额出现异常,这时候就需要进行事务回滚,确保转账操作的原子性。
- 订单流程:在线下单、付款、发货、签收等环节中,任何一个环节出现异常都需要回滚之前所有操作,以免产生不一致的订单信息或错误的订单状态。
- 数据库操作:当执行多个操作需要保证数据的完整性,避免中途出现错误导致数据异常,此时应该使用事务来保证操作的原子性。
- 数据同步:当需要将数据从一个数据源同步到另一个数据源时,如果在同步过程中出现错误,需要回滚之前的所有操作,保证数据的同步精度。