本文目录导读:

在Java中实现回滚主要有以下几种方式,具体取决于你使用的技术栈:
Spring声明式事务(最常用)
使用 @Transactional 注解
@Service
public class UserService {
@Autowired
private UserRepository userRepository;
@Autowired
private AccountRepository accountRepository;
@Transactional(rollbackFor = Exception.class) // 指定回滚异常类型
public void createUserAndAccount(User user, Account account) {
// 第一个操作
userRepository.save(user);
// 如果这里发生异常,第一个操作会自动回滚
if (user.getAge() < 0) {
throw new IllegalArgumentException("Age cannot be negative");
}
// 第二个操作
accountRepository.save(account);
}
}
手动控制回滚
@Service
public class OrderService {
@Transactional
public void createOrder(Order order) {
try {
// 执行业务逻辑
saveOrder(order);
updateInventory(order);
deductBalance(order);
} catch (Exception e) {
// 手动触发回滚
TransactionAspectSupport.currentTransactionStatus()
.setRollbackOnly();
throw e;
}
}
}
JDBC事务管理
原生JDBC实现
public class JdbcTransactionDemo {
public void transferMoney(Connection conn,
int fromAccount,
int toAccount,
double amount) throws SQLException {
conn.setAutoCommit(false); // 关闭自动提交
try {
// 扣款操作
String debitSql = "UPDATE accounts SET balance = balance - ? WHERE id = ?";
try (PreparedStatement pstmt = conn.prepareStatement(debitSql)) {
pstmt.setDouble(1, amount);
pstmt.setInt(2, fromAccount);
pstmt.executeUpdate();
}
// 如果余额不足,抛异常触发回滚
if (checkBalance(conn, fromAccount) < 0) {
throw new SQLException("Insufficient balance");
}
// 存款操作
String creditSql = "UPDATE accounts SET balance = balance + ? WHERE id = ?";
try (PreparedStatement pstmt = conn.prepareStatement(creditSql)) {
pstmt.setDouble(1, amount);
pstmt.setInt(2, toAccount);
pstmt.executeUpdate();
}
// 提交事务
conn.commit();
} catch (SQLException e) {
// 发生异常时回滚
conn.rollback();
throw e;
} finally {
conn.setAutoCommit(true); // 恢复自动提交
}
}
private double checkBalance(Connection conn, int accountId) throws SQLException {
// 查询余额的逻辑
return 1000.0; // 简化示例
}
}
Spring编程式事务管理
@Service
public class TransactionTemplateDemo {
@Autowired
private TransactionTemplate transactionTemplate;
@Autowired
private SomeRepository repository;
public void doComplexOperation() {
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus status) {
try {
// 业务操作1
repository.saveEntity1(entity1);
// 业务操作2(可能失败)
repository.saveEntity2(entity2);
} catch (Exception e) {
// 设置事务回滚
status.setRollbackOnly();
throw e;
}
}
});
}
}
自定义回滚逻辑(补偿机制)
适用于分布式系统或无法使用数据库事务的场景:
@Component
public class CompensatingTransactionDemo {
@Autowired
private ServiceA serviceA;
@Autowired
private ServiceB serviceB;
public void executeWithCompensation() {
boolean stepASuccess = false;
boolean stepBSuccess = false;
try {
// 执行步骤A
serviceA.doStepA();
stepASuccess = true;
// 执行步骤B
serviceB.doStepB();
stepBSuccess = true;
} catch (Exception e) {
log.error("Operation failed, starting compensation...");
// 执行补偿操作
if (stepASuccess) {
compensateStepA();
}
if (stepBSuccess) {
compensateStepB();
}
throw new RuntimeException("Transaction failed, compensated", e);
}
}
private void compensateStepA() {
serviceA.undoStepA();
}
private void compensateStepB() {
serviceB.undoStepB();
}
}
配置注意事项
Spring Boot 配置
spring:
datasource:
# 数据源配置
url: jdbc:mysql://localhost:3306/test
username: root
password: password
# 事务管理配置
transaction:
rollback-on-commit-failure: true
default-timeout: 30
@Transactional 注解的关键属性
@Transactional(
propagation = Propagation.REQUIRED, // 事务传播行为
isolation = Isolation.READ_COMMITTED, // 隔离级别
timeout = 30, // 超时时间(秒)
rollbackFor = {Exception.class, RuntimeException.class}, // 触发回滚的异常
noRollbackFor = {BusinessException.class} // 不触发回滚的异常
)
最佳实践
-
选择合适的回滚策略:
- 单体应用:使用声明式事务
- 分布式系统:使用Saga模式或补偿事务
-
明确回滚范围:
@Transactional(rollbackFor = Exception.class) // 默认只回滚RuntimeException,这里设置回滚所有异常
-
避免在事务中捕获异常:
// ❌ 错误示例:捕获了异常导致不回滚 @Transactional public void badExample() { try { saveData(); } catch (Exception e) { log.error("Error", e); // 异常被吃掉,事务不会回滚 } } // ✅ 正确示例:让异常传播出去 @Transactional public void goodExample() { saveData(); } -
数据库引擎选择:
- MySQL使用InnoDB(支持事务)
- 避免使用MyISAM(不支持事务)
选择合适的回滚方式取决于你的应用架构、数据一致性要求以及是否支持分布式事务。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播