我有以下代码:
@Transactional
public void handle() {
for (Item item : getItems()) {
handle(item);
}
}
@Transactional(propagation = Propagation.NESTED)
public void handle(Item item) {
/* logic here */
}假设handle()中的循环处理10项。还假设对于3个项,handle(Item)将抛出一个异常。
我的问题:
1外部事务是否在第10项之后提交?这意味着将提交对7个项的必要更改,并将其他3个项的任何中间更改回创建的保存点?
2 handle(Item)中的异常是否会被捕获,而不会被转发给handle()?这是@Transactional做的吗?
3此外,我还想了解以下流程在行为上的区别:
@Transactional
public void handle() {
for (Item item : getItems()) {
handle(item);
}
}
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void handle(Item item) {
/* logic here */
}根据我从docs的理解,这里将启动一个新事务,并暂停活动事务。这与NESTED不同,后者创建了保存点,而当前事务仍在使用中。但我相信,在REQUIRES_NEW中,7项的更改将被提交,其他3项的任何中间更改都将被遗忘。
那么,真正的区别是什么(如果有的话)?
发布于 2017-06-20 08:39:15
嵌套启动主事务的子事务。REQUIRES_NEW启动单独的事务。
如果在方法之后用REQUIRES_NEW标记一个方法,那么退出数据将保留在DB中(由单独的事务提交),不管外部事务发生了什么。
在嵌套的情况下,如果回滚外部事务,则将对更改进行回滚。
见答案这里
发布于 2017-06-20 09:14:19
根据我从docs的理解,这里将启动一个新事务,并暂停活动事务。
要在句柄()中应用句柄(项)的事务处理,您应该
@Transactional
public void handle() {
for (Item item : getItems()) {
applicationContext.getBean(your service).handle(item);
}
}
or use spring aspectj load time weaving for self-invocation (inside one service call one method from another)使用Propagation.REQUIRES_NEW内部循环调用方法--这不利于性能,您可以为每个调用创建新的事务。您可以在一个方法中包装,但只处理与业务逻辑相关的异常!并非所有类型的例外
@Transactional
public void handle() {
..some logic
//if you really need it
applicationContext.getBean(your service).handleBatch(getItems());
}
}
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void handleBatch(Collection items) {
for (Item item : items) {
applicationContext.getBean(your service).handle(item)
}
}
public void handle(Item item) {
try{
//do operation
}catch(.appropriate type..Exception ex){
//log exception!!!
}
}https://stackoverflow.com/questions/44647872
复制相似问题