【发布时间】:2016-01-23 11:26:23
【问题描述】:
我有一个基于 Spring+Hibernate 构建的应用程序。我正在尝试从文件中的条目列表将数据插入数据库。基本思想是插入所有具有有效数据的记录,并为所有未插入的条目记录错误报告。
一个服务类,即@Transactional,调用另一个服务类来读取文件并插入到数据库中。此刻,我一个接一个地插入记录。也许我会将其更改为批处理。插入在 try catch 块中执行。
伪代码:
@Transactional
class MainService {
public void insertFromFile(File inputFile) {
subServuce(toIterator(inputFile)); // toIterator(..) is just for understanding.
}
}
class SubService {
public void insert(Iterator input) {
while (input.hasNext()) {
try {
DBService.save(input.next());
} catch (Exception e) {
// Log the error and continue with next records
}
}
}
}
@Transactional
class DBService {
public void save(Data input) {
generalDao.save(input);
}
}
试过了:
class SubService {
public void insert(Iterator input) {
while (input.hasNext()) {
try {
save(input.next());
} catch (Exception e) {
// Log the error and continue with next records
}
}
}
// @Transactional(propagation = Propagation.REQUIRES_NEW, noRollbackFor = Exception.class)
@Transactional(propagation = Propagation.NOT_SUPPORTED, noRollbackFor = Exception.class)
public void save(Data input) {
DBService.save(input);
}
}
即使处理了异常,整个事务也在回滚,我收到此错误Could not commit JPA transaction; nested exception is javax.persistence.RollbackException: Transaction marked as rollbackOnly
我尝试在SubService.insert(..) 上指定@Transactional(noRollBack = Exception.class),但没有成功。
以下是我的问题:
- 如何告诉 Spring 不要回滚并继续处理其他记录。
- 在插入多条记录时不回滚是一种好习惯吗?这不违反原子性规则吗?
-
在批处理中,这是如何处理的?如果发生错误是全部插入还是不插入?
解决方案:
在@Madhusudana Reddy Sunnapu 的回答的帮助下,能够解决这个问题。
使用 Propagation.REQUIRES_NEW 在 SubService 和 DBService 之间创建了一个层。问题是即使 SubService.save(..) 使用 @Transactional 进行注释,因为它属于同一个 Bean,代理不会将其视为不同的会话。
SubServiceDao {
// @Transactional(propagation = Propagation.REQUIRES_NEW)
public void save(Data input) {
DBService.save(input);
}
}
class SubService {
public void insert(Iterator input) {
while (input.hasNext()) {
try {
SubServiceDao.save(input.next());
} catch (Exception e) {
// Log the error and continue with next records
}
}
}
}
【问题讨论】:
-
stackoverflow.com/questions/54343137/…
标签: java spring hibernate jpa transactional