我有以下使用Spring @Transactional批注的代码。
//in A.java
Class A {
@Transactional(propagation=propagation.???)
public void aMethod() {
B b = new B();
b.bMethod(); // success and committed
aPrivateMethod(); // failure
}
private void aPrivateMethod() { //something }
}
//in B.java
Class B {
@Transactional(propagation=propagation.???)
public void bMethod() { //something }
}
我期望的A.aMethod()行为是:
如果b.bMethod()成功并已提交但aPrivateMethod()失败, 然后A.aMethod()会回滚,包括b.bMethod()。
如何设置@Transactional传播参数来实现这一目标?
答案 0 :(得分:1)
这是结论。
示例1
'password,client_credentials,refresh_token'
示例2
// A.java
class A {
@Transactional(rollbackFor = Exception.class)
public void aMethod() {
B b = new B();
try {
b.bMethod("111", false); // bMethod() is NOT rolled back, record of "111" has been created
} catch (Exception e) {
// Do nothing, let it go
}
b.bMethod("222", true); // record of "222" has been created
}
// The annotation below is ignored
@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW)
public void bMethod(String id, bool success) {
createRecordInDB(id);
if (!success) {
throw new Exception("Throw exception explicitly!");
}
}
}
示例3
// A.java
class A {
@Transactional(rollbackFor = Exception.class)
public void aMethod() {
B b = new B();
b.bMethod("111", true); // record of "111" has been rolled back and NOT created
b.bMethod("222", true); // record of "222" has been rolled back and NOT created
createRecordInDB("333"); // record of "333" has been rolled back and NOT created
throw new Exception("Throw exception explicitly!");
}
// The annotation below is ignored
@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW)
public void bMethod(String id, bool success) {
createRecordInDB(id);
if (!success) {
throw new Exception("Throw exception explicitly!");
}
}
}
示例4
// A.java
class A {
@Transactional(rollbackFor = Exception.class)
public void aMethod() {
B b = new B();
try {
b.bMethod("111", false); // bMethod() has been rolled back, record of "111" has NOT been created
} catch (Exception e) {
// Do nothing, let it go
}
b.bMethod("222", true); // record of "222" has been created
}
}
// B.java
class B {
@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW)
public void bMethod(String id, bool success) {
createRecordInDB(id);
if (!success) {
throw new Exception("Throw exception explicitly!");
}
}
}
答案 1 :(得分:0)
所有已发布的示例将打开一个新的交易环境,而与任何外部交易无关。因此,REQUIRES_NEW仅在此范围内的事务块和回滚更改中起作用。 您只需要提供:
Class A {
@Transactional(propagation=Propagation.REQUIRED)
public void aMethod() {
B b = new B();
b.bMethod(); // success and committed
aPrivateMethod(); // failure
}
private void aPrivateMethod() { //something }
}