Spring 外层事务失败回滚内层事务
Spring outer transaction failure roll back inner transaction
我有以下使用 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() 的行为是:
If b.bMethod() succeeds and has committed but aPrivateMethod() fails,
then A.aMethod() is rolled back including b.bMethod().
如何设置@Transactional 传播参数来实现此目的?
结论是这样的。
示例 1
// 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!");
}
}
}
示例 2
// 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!");
}
}
}
示例 3
// 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!");
}
}
}
示例 4
// A.java
class A {
@Transactional(rollbackFor = Exception.class)
public void aMethod() {
B b = new B();
b.bMethod("111", true); // record of "111" has been created
b.bMethod("222", true); // record of "222" has been created
createRecordInDB("333"); // record of "333" has been rolled back and NOT created
throw new Exception("Throw exception explicitly!");
}
}
// 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!");
}
}
}
所有发布的示例都将打开一个新的事务上下文,而不管任何外部事务。因此 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 }
}
我有以下使用 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() 的行为是:
If b.bMethod() succeeds and has committed but aPrivateMethod() fails, then A.aMethod() is rolled back including b.bMethod().
如何设置@Transactional 传播参数来实现此目的?
结论是这样的。
示例 1
// 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!");
}
}
}
示例 2
// 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!");
}
}
}
示例 3
// 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!");
}
}
}
示例 4
// A.java
class A {
@Transactional(rollbackFor = Exception.class)
public void aMethod() {
B b = new B();
b.bMethod("111", true); // record of "111" has been created
b.bMethod("222", true); // record of "222" has been created
createRecordInDB("333"); // record of "333" has been rolled back and NOT created
throw new Exception("Throw exception explicitly!");
}
}
// 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!");
}
}
}
所有发布的示例都将打开一个新的事务上下文,而不管任何外部事务。因此 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 }
}