玩命加载中🤣🤣🤣

Spring中事务管理


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

this 索引失效

针对这种方式对齐改造,拿到当前类的代理类对象,通过代理类调用局部方法即可实现细粒度事务处理

@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;
}

文章作者: 👑Dee👑
版权声明: 本博客所有文章除特別声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 👑Dee👑 !
  目录