/*
 *  Copyright 1999-2019 Seata.io Group.
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package io.seata.rm;

import java.util.concurrent.Callable;

import io.seata.core.context.RootContext;

/**
 * Template of executing business logic in a local transaction with Global lock.
 *
 * @param <T>
 * @author deyou
 */
public class GlobalLockTemplate<T> {

    /**
     * Execute object.
     *
     * @param business the business
     * @return the object
     * @throws Exception
     */
    public Object execute(Callable<T> business) throws Exception {

        Object rs;
        try {
            // add global lock declare
            RootContext.bindGlobalLockFlag();

            // Do Your Business
            rs = business.call();
        } finally {
            //clean the global lock declare
            RootContext.unbindGlobalLockFlag();
        }

        return rs;
    }

}

@@ -1105,52 +1105,164 @@
     
-try %7B%0A            // add global lock declare
+//fix nested situation%0A        boolean hasInGlobalLock = RootContext.requireGlobalLock();%0A        // add global lock declare%0A        if (!hasInGlobalLock) %7B
 %0A   
@@ -1304,17 +1304,40 @@
 Flag();%0A
+        %7D%0A        try %7B
 %0A
-
         
@@ -1450,32 +1450,72 @@
 al lock declare%0A
+            if (!hasInGlobalLock) %7B%0A    
             Root
@@ -1538,32 +1538,46 @@
 obalLockFlag();%0A
+            %7D%0A
         %7D%0A%0A     

fix nested GlobalLock unbind prematurely (#2698)