gpt4 book ai didi

java - 在 @Transactional 中提交 try-catch 中的更改

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:06:05 24 4
gpt4 key购买 nike

考虑我有一个方法以 ActiveRecord 模式风格做一些事情和日志记录机制:

@Transactional
public void doSmt() {
try {
someOperation(); // can throw exception
Logger.logIntoDb(); // if everything is OK
} catch {Exception e} {
Logger.logIntoDbWithException(e.getMessage()); // log error into db

throw new MyCustomException(e);
}
}

public static void logIntoDbWithException(String message) {
final LogEntry logEntry = new LogEntry();
logEntry.setDate(new Date());
logEntry.setMessage(message);
logEntry.persist();
}

我想在失败的情况下保留一条错误消息,但如果我在 catch 子句中重新抛出异常,事务将被回滚并且我的 LogEntry 将不会保留。我看到的唯一方法是在 persist() 之后手动调用 flush()

是否有更干净的解决方案来执行此操作?

谢谢。

更新:

因为我有一个执行持久化的静态方法,所以我需要将以下 hack 应用于已接受的答案:

public static void logIntoDbWithException(String message) {
new Runnable() {
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void run() {
final LogEntry logEntry = new LogEntry();
logEntry.setDate(new Date());
logEntry.setMessage(message);
logEntry.persist();
}
}.run();
}

最佳答案

首先,调用 flush() 不会给您带来任何好处:flush() 不会提交任何内容,并且当您在同一事务中记录错误时,插入将被回滚。

因此,您需要启动一个新的“嵌套”事务来记录错误。

public class A {

@Autowired
private B b;

@Transactional
public void doSmt() {
try {
someOperation(); // can throw exception
b.logIntoDb(); // if everything is OK
} catch {Exception e} {
b.logIntoDbWithException(e.getMessage()); // log error into db

throw new MyCustomException(e);
}
}
}

public class B{

//outer transaction is still active
public void logIntoDb(String message) {
final LogEntry logEntry = new LogEntry();
logEntry.setDate(new Date());
logEntry.setMessage(message);
logEntry.persist();
}

// 'outer' transaction will be suspended until this method completes
// this new transaction will commit/rollback independently of the outer transaction
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void logIntoDbWithException(String message) {
final LogEntry logEntry = new LogEntry();
logEntry.setDate(new Date());
logEntry.setMessage(message);
logEntry.persist();
}
}

关于java - 在 @Transactional 中提交 try-catch 中的更改,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36908407/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com