我希望在出现错误时回滚数据的事务,同时将错误写入数据库。
我不能处理事务注释。
下面的代码生成一个运行时错误(1/0),并且仍然将数据写入数据库。并将数据写入错误表。
在StackOverflow中,我尝试了几种变体,并遵循类似的问题,但没有成功。
谁有一个提示,怎么办?
@Service
public class MyService{
@Transactional(rollbackFor = Exception.class)
public void updateData() {
try{
processAndPersist(); // <- db operation with inserts
int i = 1/0; // <- Runtime error
}catch (Exception e){
persistError()
trackReportError(filename, e.getMessage());
}
}
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void persistError(String message) {
persistError2Db(message); // <- db operation with insert
}
您需要在updateData()
方法中抛出异常的方法来回滚事务。同时不需要回滚事务。
@Transactional(rollbackFor = Exception.class)
public void updateData() {
try{
processAndPersist(); // <- db operation with inserts
int i = 1/0; // <- Runtime error
}catch (Exception e){
persistError()
trackReportError(filename, e.getMessage());
throw ex; // if throw error here, will not work
}
}
仅仅抛出一个错误是没有用的,因为持久错误()
将具有与updateData()
相同的事务。因为使用此引用(而不是对代理的引用)调用持久性错误()
。
解决方案
updateData()
(和事务)外移动的持久错误()
调用。删除@Transactional
从持久性错误()
(它将不工作),并在持久性错误2Db()
中使用仓库
的事务。 持久错误()
到一个单独的服务器。在这种情况下,将使用代理调用它。 @Transactional
注释)。使用程序化事务管理手动设置事务边界https://docs.spring.io/spring-framework/docs/3.0.0.M3/reference/html/ch11s06.html还要记住,persistError()
也会产生错误(并且很可能会产生错误)。
使用自我参照
您可以使用对MyService的自我引用来进行事务处理,因为您将能够调用的不是MyServiceImpl
的方法,而是Spring代理的方法。
@Service
public class MyServiceImpl implements MyService {
public void doWork(MyService self) {
DataEntity data = loadData();
try {
self.updateData(data);
} catch (Exception ex) {
log.error("Error for dataId={}", data.getId(), ex);
self.persistError("Error");
trackReportError(filename, ex);
}
}
@Transactional
public void updateData(DataEntity data) {
persist(data); // <- db operation with inserts
}
@Transactional
public void persistError(String message) {
try {
persistError2Db(message); // <- db operation with insert
} catch (Exception ex) {
log.error("Error for message={}", message, ex);
}
}
}
public interface MyService {
void doWork(MyService self);
void updateData(DataEntity data);
void persistError(String message);
}
要使用
MyService service = ...;
service.doWork(service);
我们在SQL Server存储过程中使用以下错误处理模式: 但是当存储过程中出现以下错误时,try/catch块不起作用。 错误详细信息:存储过程试图将值插入非NULL列。 在执行存储过程中,我得到了以下错误 EXECUTE之后的事务计数表示BEGIN和COMMIT语句的数量不匹配。上一个计数=1,当前计数=0。 msg 3903, Level 16, State 1, Line 30 ROLLB
Catch 从onError通知中恢复发射数据 Catch操作符拦截原始Observable的onError通知,将它替换为其它的数据项或数据序列,让产生的Observable能够正常终止或者根本不终止。 在某些ReactiveX的实现中,有一个叫onErrorResumeNext的操作符,它的行为与Catch相似。 RxJava将Catch实现为三个不同的操作符: onErrorReturn 让
这个块似乎没有捕获发生的错误,这很奇怪,考虑到我对网站的注册部分有一个类似的块。这将处理登录。该错误发生在第三行 并引发此错误: 当电子邮件格式错误时会发生这种情况,例如。因此,当它是时,我希望在块中设置错误消息。 有人知道为什么这个< code>try catch不起作用吗?
不管你多么精通编程,有时我们的脚本总还是会出现错误。可能是因为我们的编写出错,或是与预期不同的用户输入,或是错误的服务端响应以及其他数千种原因。 通常,如果发生错误,脚本就会“死亡”(立即停止),并在控制台将错误打印出来。 但是有一种语法结构 try..catch,它使我们可以“捕获(catch)”错误,因此脚本可以执行更合理的操作,而不是死掉。 “try…catch” 语法 try..catch
在happy path场景中,我有一个spring批处理工作,但现在我将重点放在错误处理上。 但是,在另一个测试中,我想证明一个不可预见的数据库错误会导致作业失败。为此,我创建了一个触发器,该触发器会导致对要插入的表的插入失败。 这似乎起作用了,在writer执行之后,在事务提交期间抛出异常,并且我得到以下日志消息: 这似乎也是预期的行为。问题是,这并不能阻止工作。该步骤退出到SimplyRetr
我需要在我的存储过程中添加错误处理。我相信当只有一个insert语句时,通常不需要使用BEGIN TRAN/COMMIT TRAN。还有使用SET XACT_ABORT,NOCOUNT ON语句的意义是什么。请给出最佳/标准的方法将错误处理添加到下面的SP中。如果出现错误,我还需要在catch段中调用dbo.usp_get_error_info。请建议。