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

考虑一下我有一个方法以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将不会保留。我看到的唯一方法是手动调用flush()after

persist()

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

谢谢。

由于我有一个执行持久化的静态方法,因此我需要对接受的答案应用以下技巧:

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();

}

}

以上是 在@Transactional内部提交try-catch中的更改 的全部内容, 来源链接: utcz.com/qa/404953.html

回到顶部