Spring中事务管理
使用背景
一般情况下,业务场景中可以使用 Spring 提供的 @Transactional 注解来把事务的管理交给框架来处理,框架通过 AOP 的一个 Aspect 来创建和维护事务,帮我们把事务管理和业务逻辑分开。但是通常情况下一个 service 会有较为复杂的 SQL 逻辑,事务的力度相对也会较大。
@Override
@Transactional
public void test() {
this.testSave01();
this.testSave02();
}
@Transactional 失效
- 在类的内部调用类内的用 @Transactional 标注的方法
@Override
public void test() {
this.testSave01();
this.testSave02();
}
public void testSave01() {
//逻辑...
}
@Transactional
public void testSave02() {
//逻辑...
}
-
类内部的方法不通过代理调用,而是通过类的 this 调用,调用的是自身,代理方法未被调用。
-
事务方法内的异常被 catch 之后未抛出新的异常
@Transactional
public void test2(){
// 异常被捕捉到之后未抛出新的异常,事务失效
try{
// 更新数据
} catch (Exception e){
e.printStackTrace();
}
}
代理方法看到的是无异常,所以不会回滚事务。
TransactionTemplate
无返回值
/**
* 关键包
*/
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;
private final TransactionTemplate transactionTemplate;
public BlogCommentsServiceImpl(PlatformTransactionManager transactionManager) {
this.transactionTemplate = new TransactionTemplate(transactionManager);
}
@Override
public void test() {
this.test01();
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {
test02();
}
});
}
public void test01() {
BlogComments blogComments = new BlogComments();
//blogComments.set(xxx)
this.save(blogComments);
}
public void test02() {
BlogComments blogComments = new BlogComments();
//blogComments.set(xxx)
this.save(blogComments);
int a = 1 / 0;
}
有返回值
常规写法
/**
* 关键包: 如果报错查看包是否导错
*/
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionTemplate;
//省略类名
private final TransactionTemplate transactionTemplate;
public BlogCommentsServiceImpl(PlatformTransactionManager transactionManager) {
this.transactionTemplate = new TransactionTemplate(transactionManager);
}
@Override
public void test() {
this.test01();
Boolean result = transactionTemplate.execute(new TransactionCallback<Boolean>() {
@Override
public Boolean doInTransaction(TransactionStatus transactionStatus) {
return test02();
}
});
System.out.println(result);
}
public Boolean test01() {
BlogComments blogComments = new BlogComments();
//blogComments.set(xxx);
this.save(blogComments);
return true;
}
public Boolean test02() {
BlogComments blogComments = new BlogComments();
//blogComments.set(xxx);
this.save(blogComments);
int a = 1 / 0;
return true;
}
Lambda 写法
//service 方法
@Override
public void test() {
this.test01();
Boolean result = transactionTemplate.execute(transactionStatus -> test02());
System.out.println(result);
}
自定义异常处理
常规写法
private final TransactionTemplate transactionTemplate;
public BlogCommentsServiceImpl(PlatformTransactionManager transactionManager) {
this.transactionTemplate = new TransactionTemplate(transactionManager);
}
@Override
public void test() {
test01();
transactionTemplate.execute(new TransactionCallbackWithoutResult(){
@Override
protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {
try {
test02();
} catch (Exception e) {
transactionStatus.setRollbackOnly();
}
}
});
}
public Boolean test01() {
BlogComments blogComments = new BlogComments();
//blogComments.set(xxx);
this.save(blogComments);
return true;
}
public Boolean test02() {
BlogComments blogComments = new BlogComments();
//blogComments.set(xxx);
this.save(blogComments);
int a = 1 / 0;
return true;
}
Lambda 写法
@Override
public void testTryCatch() {
this.test01();
Boolean result = transactionTemplate.execute(status -> {
try {
return test02();
} catch (Exception e) {
//逻辑处理
status.setRollbackOnly();
throw new RuntimeException();
}
});
System.out.println(result);
}
public Boolean test02() {
BlogComments blogComments = new BlogComments();
//blogComments.set(xxx);
this.save(blogComments);
int a = 1 / 0;
return true;
}
参数设定
//截取自官网
public class SimpleService implements Service {
private final TransactionTemplate transactionTemplate;
public SimpleService(PlatformTransactionManager transactionManager) {
this.transactionTemplate = new TransactionTemplate(transactionManager);
// the transaction settings can be set here explicitly if so desired
this.transactionTemplate.setIsolationLevel(TransactionDefinition.ISOLATION_READ_UNCOMMITTED);
this.transactionTemplate.setTimeout(30); // 30 seconds
// and so forth...
}
}
TransactionManager
使用 PlatformTransactionManager
@Resource
private PlatformTransactionManager txManager;
@Override
public void test() {
test01();
DefaultTransactionDefinition def = new DefaultTransactionDefinition();
// explicitly setting the transaction name is something that can be done only programmatically
def.setName("SomeTxName");
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
TransactionStatus status = txManager.getTransaction(def);
try {
// put your business logic here
test02();
} catch (Exception ex) {
txManager.rollback(status);
throw ex;
}
txManager.commit(status);
}
public Boolean test01() {
BlogComments blogComments = new BlogComments();
//blogComments.set(xxx);
this.save(blogComments);
return true;
}
public Boolean test02() {
BlogComments blogComments = new BlogComments();
//blogComments.set(xxx);
this.save(blogComments);
int a = 1 / 0;
return true;
}
代理类结合 @Transactional
针对这种方式对齐改造,拿到当前类的代理类对象,通过代理类调用局部方法即可实现细粒度事务处理
@Override
public void testProxy() {
test01();
IBlogCommentsService proxy = (IBlogCommentsService) AopContext.currentProxy();
proxy.tProxy();
}
@Override
@Transactional
public void tProxy() {
BlogComments blogComments = new BlogComments();
//blogComments.set(xxx);
this.save(blogComments);
int a = 1 / 0;
}