猿问

在 Spring 的当前线程中禁止 @Transactional

我正在寻找下一个问题的解决方案。我使用 Spring 并且我有一些不应被阻止的执行程序线程(至少读/写数据库)。有几个任务可以通过这个执行器执行,我不知道哪个可以使用@Transactional方法或任何其他方式来访问数据库。我想禁止在执行者线程中打开新事务,怎么做?


小例子


@Component

public class Service {


    public void execute() {

        System.out.println("I don't need transaction to execute");

    }

}


@Component

public class Service2 {


    @Transactional

    public void execute() {

        System.out.println("I've opened new transaction!");

    }

}


@Component

public class NonTransactionalExecutor {


    @Autowired

    private ThreadPoolExecutor threadPoolExecutor;


    @Autowired

    private Service service;


    @@Autowired

    private Service2 service2;


    public void doInExecutor() {

        threadPoolExecutor.execute(new Runnable() {

            @Override

            public void run() {

                // Is there anything I could do to get exception on service2.execute?

                service.execute();

                service2.execute();

            }

        });

    }

}

PS 在现实世界中,当方法被注释时,@Transactional它会尝试TransactionManager使用数据库中的当前值打开新事务(我使用的是 Postgres)。


慕慕森
浏览 344回答 1
1回答

智慧大石

您可能可以为此使用装饰器模式。实现您自己的PlatformTransactionManager并将您当前的经理作为委托传递给它。在 中getTransaction,如果当前线程不是您所期望的,则抛出异常。public class MyTransactionManager implements PlatformTransactionManager {    private final PlatformTransactionManager delegate;    public MyTransactionManager(PlatformTransactionManager delegate) {        this.delegate = delegate;    }    @Override    public void commit(TransactionStatus status) {        delegate.commit(status);    }    @Override    public TransactionStatus getTransaction(TransactionDefinition definition) {        if (Thread.getCurrentThread() == /*something*/) {            return delegate.getTransaction(definition);        }        else {            throw new RuntimeException();        }    }    @Override    public void rollback(TransactionStatus status) {        delegate.rollback(status);    }}
随时随地看视频慕课网APP

相关分类

Java
我要回答