001/**
002 * Copyright (c) 2015-2022, Michael Yang 杨福海 (fuhai999@gmail.com).
003 * <p>
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 * <p>
008 * http://www.apache.org/licenses/LICENSE-2.0
009 * <p>
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package io.jboot.support.seata.interceptor;
017
018import com.jfinal.aop.Interceptor;
019import com.jfinal.aop.Invocation;
020import io.jboot.support.seata.JbootSeataManager;
021import io.jboot.support.seata.annotation.SeataGlobalLock;
022import io.jboot.support.seata.annotation.SeataGlobalTransactional;
023import io.seata.core.model.GlobalLockConfig;
024import io.seata.rm.GlobalLockExecutor;
025
026import java.lang.reflect.Method;
027
028/***
029 *
030 * @author Hobbit Leon_wy@163.com , Michael Yang (fuhai99@gmail.com)
031 * 参考:https://github.com/seata/seata/blob/develop/spring/src/main/java/
032 * io/seata/spring/annotation/GlobalTransactionalInterceptor.java
033 *
034 */
035public class SeataGlobalTransactionalInterceptor implements Interceptor {
036
037    public SeataGlobalTransactionalInterceptor() {
038    }
039
040    @Override
041    public void intercept(Invocation inv) {
042        if (!JbootSeataManager.me().isEnable()) {
043            inv.invoke();
044            return;
045        }
046        Method method = inv.getMethod();
047        final SeataGlobalTransactional globalTrxAnno = method.getAnnotation(SeataGlobalTransactional.class);
048        final SeataGlobalLock globalLockAnno = method.getAnnotation(SeataGlobalLock.class);
049        try {
050            if (globalTrxAnno != null) {
051                handleGlobalTransaction(inv, globalTrxAnno);
052            } else if (globalLockAnno != null) {
053                handleGlobalLock(inv,globalLockAnno);
054            } else {
055                inv.invoke();
056            }
057        } catch (Throwable e) {
058            e.printStackTrace();
059            throw new RuntimeException(e);
060        }
061
062    }
063
064    private void handleGlobalLock(final Invocation inv, final SeataGlobalLock globalLockAnno) throws Throwable {
065        JbootSeataManager.me().getGlobalLockTemplate().execute(new GlobalLockExecutor() {
066            @Override
067            public Object execute() throws Throwable {
068                inv.invoke();
069                return inv.getReturnValue();
070            }
071
072            @Override
073            public GlobalLockConfig getGlobalLockConfig() {
074                GlobalLockConfig config = new GlobalLockConfig();
075                config.setLockRetryInterval(globalLockAnno.lockRetryInterval());
076                config.setLockRetryTimes(globalLockAnno.lockRetryTimes());
077                return config;
078            }
079        });
080    }
081
082    private Object handleGlobalTransaction(final Invocation invocation, final SeataGlobalTransactional globalTrxAnno) throws Throwable {
083       return SeataGlobalTransactionHandler.handleGlobalTransaction(invocation,globalTrxAnno);
084    }
085
086
087}