Search in sources :

Example 6 with GlobalSession

use of io.seata.server.session.GlobalSession in project seata by seata.

the class SessionStoreTest method testRestoredFromFile2.

/**
 * Test restored from file 2.
 *
 * @throws Exception the exception
 */
// @Test
public void testRestoredFromFile2() throws Exception {
    try {
        SessionHolder.init("file");
        GlobalSession globalSession = new GlobalSession("demo-app", "my_test_tx_group", "test", 6000);
        globalSession.addSessionLifecycleListener(SessionHolder.getRootSessionManager());
        globalSession.begin();
        // Re-init SessionHolder: restore sessions from file
        SessionHolder.init("file");
    } finally {
        SessionHolder.destroy();
    }
}
Also used : GlobalSession(io.seata.server.session.GlobalSession)

Example 7 with GlobalSession

use of io.seata.server.session.GlobalSession in project seata by seata.

the class SessionStoreTest method testRestoredFromFile.

/**
 * Test restored from file.
 *
 * @throws Exception the exception
 */
@Test
public void testRestoredFromFile() throws Exception {
    try {
        SessionHolder.init("file");
        GlobalSession globalSession = new GlobalSession("demo-app", "my_test_tx_group", "test", 6000);
        String xid = XID.generateXID(globalSession.getTransactionId());
        globalSession.setXid(xid);
        globalSession.addSessionLifecycleListener(SessionHolder.getRootSessionManager());
        globalSession.begin();
        BranchSession branchSession1 = SessionHelper.newBranchByGlobal(globalSession, BranchType.AT, RESOURCE_ID, "ta:1,2;tb:3", "xxx");
        branchSession1.setXid(xid);
        branchSession1.lock();
        globalSession.addBranch(branchSession1);
        LockManager lockManager = new FileLockManagerForTest();
        String otherXID = XID.generateXID(0L);
        Assertions.assertFalse(lockManager.isLockable(otherXID, RESOURCE_ID, "ta:1"));
        Assertions.assertFalse(lockManager.isLockable(otherXID, RESOURCE_ID, "ta:2"));
        Assertions.assertFalse(lockManager.isLockable(otherXID, RESOURCE_ID, "tb:3"));
        Assertions.assertTrue(lockManager.isLockable(otherXID, RESOURCE_ID, "ta:4"));
        Assertions.assertTrue(lockManager.isLockable(otherXID, RESOURCE_ID, "tb:5"));
        lockManager.cleanAllLocks();
        Assertions.assertTrue(lockManager.isLockable(otherXID, RESOURCE_ID, "ta:1"));
        Assertions.assertTrue(lockManager.isLockable(otherXID, RESOURCE_ID, "ta:2"));
        Assertions.assertTrue(lockManager.isLockable(otherXID, RESOURCE_ID, "tb:3"));
        // Re-init SessionHolder: restore sessions from file
        SessionHolder.init("file");
        long tid = globalSession.getTransactionId();
        GlobalSession reloadSession = SessionHolder.findGlobalSession(globalSession.getXid());
        Assertions.assertNotNull(reloadSession);
        Assertions.assertFalse(globalSession == reloadSession);
        Assertions.assertEquals(globalSession.getApplicationId(), reloadSession.getApplicationId());
        Assertions.assertFalse(lockManager.isLockable(otherXID, RESOURCE_ID, "ta:1"));
        Assertions.assertFalse(lockManager.isLockable(otherXID, RESOURCE_ID, "ta:2"));
        Assertions.assertFalse(lockManager.isLockable(otherXID, RESOURCE_ID, "tb:3"));
        Assertions.assertTrue(lockManager.isLockable(xid, RESOURCE_ID, "tb:3"));
        // clear
        reloadSession.addSessionLifecycleListener(SessionHolder.getRootSessionManager());
        reloadSession.end();
    } finally {
        SessionHolder.destroy();
    }
}
Also used : LockManager(io.seata.server.lock.LockManager) FileLockManagerForTest(io.seata.server.lock.file.FileLockManagerForTest) GlobalSession(io.seata.server.session.GlobalSession) BranchSession(io.seata.server.session.BranchSession) Test(org.junit.jupiter.api.Test) FileLockManagerForTest(io.seata.server.lock.file.FileLockManagerForTest)

Example 8 with GlobalSession

use of io.seata.server.session.GlobalSession in project seata by seata.

the class SessionStoreTest method testRestoredFromFileAsyncCommitting.

/**
 * Test restored from file async committing.
 *
 * @throws Exception the exception
 */
@Test
public void testRestoredFromFileAsyncCommitting() throws Exception {
    try {
        SessionHolder.init("file");
        GlobalSession globalSession = new GlobalSession("demo-app", "my_test_tx_group", "test", 6000);
        String xid = XID.generateXID(globalSession.getTransactionId());
        globalSession.setXid(xid);
        globalSession.addSessionLifecycleListener(SessionHolder.getRootSessionManager());
        globalSession.begin();
        BranchSession branchSession1 = SessionHelper.newBranchByGlobal(globalSession, BranchType.AT, RESOURCE_ID, "ta:1", "xxx");
        Assertions.assertTrue(branchSession1.lock());
        globalSession.addBranch(branchSession1);
        LockManager lockManager = new FileLockManagerForTest();
        String otherXID = XID.generateXID(0L);
        Assertions.assertFalse(lockManager.isLockable(otherXID, RESOURCE_ID, "ta:1"));
        globalSession.changeStatus(GlobalStatus.AsyncCommitting);
        lockManager.cleanAllLocks();
        Assertions.assertTrue(lockManager.isLockable(otherXID, RESOURCE_ID, "ta:1"));
        // Re-init SessionHolder: restore sessions from file
        SessionHolder.init("file");
        long tid = globalSession.getTransactionId();
        GlobalSession reloadSession = SessionHolder.findGlobalSession(globalSession.getXid());
        Assertions.assertEquals(reloadSession.getStatus(), GlobalStatus.AsyncCommitting);
        GlobalSession sessionInAsyncCommittingQueue = SessionHolder.getAsyncCommittingSessionManager().findGlobalSession(globalSession.getXid());
        Assertions.assertTrue(reloadSession == sessionInAsyncCommittingQueue);
        // No locking for session in AsyncCommitting status
        Assertions.assertTrue(lockManager.isLockable(otherXID, RESOURCE_ID, "ta:1"));
        // clear
        reloadSession.addSessionLifecycleListener(SessionHolder.getRootSessionManager());
        reloadSession.end();
    } finally {
        SessionHolder.destroy();
    }
}
Also used : LockManager(io.seata.server.lock.LockManager) FileLockManagerForTest(io.seata.server.lock.file.FileLockManagerForTest) GlobalSession(io.seata.server.session.GlobalSession) BranchSession(io.seata.server.session.BranchSession) Test(org.junit.jupiter.api.Test) FileLockManagerForTest(io.seata.server.lock.file.FileLockManagerForTest)

Example 9 with GlobalSession

use of io.seata.server.session.GlobalSession in project seata by seata.

the class DefaultCore method commit.

@Override
public GlobalStatus commit(String xid) throws TransactionException {
    GlobalSession globalSession = SessionHolder.findGlobalSession(xid);
    if (globalSession == null) {
        return GlobalStatus.Finished;
    }
    globalSession.addSessionLifecycleListener(SessionHolder.getRootSessionManager());
    // just lock changeStatus
    boolean shouldCommit = SessionHolder.lockAndExecute(globalSession, () -> {
        // Highlight: Firstly, close the session, then no more branch can be registered.
        globalSession.closeAndClean();
        if (globalSession.getStatus() == GlobalStatus.Begin) {
            if (globalSession.canBeCommittedAsync()) {
                globalSession.asyncCommit();
                return false;
            } else {
                globalSession.changeStatus(GlobalStatus.Committing);
                return true;
            }
        }
        return false;
    });
    if (shouldCommit) {
        boolean success = doGlobalCommit(globalSession, false);
        // If successful and all remaining branches can be committed asynchronously, do async commit.
        if (success && globalSession.hasBranch() && globalSession.canBeCommittedAsync()) {
            globalSession.asyncCommit();
            return GlobalStatus.Committed;
        } else {
            return globalSession.getStatus();
        }
    } else {
        return globalSession.getStatus() == GlobalStatus.AsyncCommitting ? GlobalStatus.Committed : globalSession.getStatus();
    }
}
Also used : GlobalSession(io.seata.server.session.GlobalSession)

Example 10 with GlobalSession

use of io.seata.server.session.GlobalSession in project seata by seata.

the class DefaultCore method doGlobalRollback.

@Override
public boolean doGlobalRollback(GlobalSession globalSession, boolean retrying) throws TransactionException {
    boolean success = true;
    // start rollback event
    eventBus.post(new GlobalTransactionEvent(globalSession.getTransactionId(), GlobalTransactionEvent.ROLE_TC, globalSession.getTransactionName(), globalSession.getApplicationId(), globalSession.getTransactionServiceGroup(), globalSession.getBeginTime(), null, globalSession.getStatus()));
    if (globalSession.isSaga()) {
        success = getCore(BranchType.SAGA).doGlobalRollback(globalSession, retrying);
    } else {
        Boolean result = SessionHelper.forEach(globalSession.getReverseSortedBranches(), branchSession -> {
            BranchStatus currentBranchStatus = branchSession.getStatus();
            if (currentBranchStatus == BranchStatus.PhaseOne_Failed) {
                globalSession.removeBranch(branchSession);
                return CONTINUE;
            }
            try {
                BranchStatus branchStatus = branchRollback(globalSession, branchSession);
                switch(branchStatus) {
                    case PhaseTwo_Rollbacked:
                        globalSession.removeBranch(branchSession);
                        LOGGER.info("Rollback branch transaction successfully, xid = {} branchId = {}", globalSession.getXid(), branchSession.getBranchId());
                        return CONTINUE;
                    case PhaseTwo_RollbackFailed_Unretryable:
                        SessionHelper.endRollbackFailed(globalSession);
                        LOGGER.info("Rollback branch transaction fail and stop retry, xid = {} branchId = {}", globalSession.getXid(), branchSession.getBranchId());
                        return false;
                    default:
                        LOGGER.info("Rollback branch transaction fail and will retry, xid = {} branchId = {}", globalSession.getXid(), branchSession.getBranchId());
                        if (!retrying) {
                            globalSession.queueToRetryRollback();
                        }
                        return false;
                }
            } catch (Exception ex) {
                StackTraceLogger.error(LOGGER, ex, "Rollback branch transaction exception, xid = {} branchId = {} exception = {}", new String[] { globalSession.getXid(), String.valueOf(branchSession.getBranchId()), ex.getMessage() });
                if (!retrying) {
                    globalSession.queueToRetryRollback();
                }
                throw new TransactionException(ex);
            }
        });
        // Return if the result is not null
        if (result != null) {
            return result;
        }
        // In db mode, there is a problem of inconsistent data in multiple copies, resulting in new branch
        // transaction registration when rolling back.
        // 1. New branch transaction and rollback branch transaction have no data association
        // 2. New branch transaction has data association with rollback branch transaction
        // The second query can solve the first problem, and if it is the second problem, it may cause a rollback
        // failure due to data changes.
        GlobalSession globalSessionTwice = SessionHolder.findGlobalSession(globalSession.getXid());
        if (globalSessionTwice != null && globalSessionTwice.hasBranch()) {
            LOGGER.info("Rollbacking global transaction is NOT done, xid = {}.", globalSession.getXid());
            return false;
        }
    }
    if (success) {
        SessionHelper.endRollbacked(globalSession);
        // rollbacked event
        eventBus.post(new GlobalTransactionEvent(globalSession.getTransactionId(), GlobalTransactionEvent.ROLE_TC, globalSession.getTransactionName(), globalSession.getApplicationId(), globalSession.getTransactionServiceGroup(), globalSession.getBeginTime(), System.currentTimeMillis(), globalSession.getStatus()));
        LOGGER.info("Rollback global transaction successfully, xid = {}.", globalSession.getXid());
    }
    return success;
}
Also used : TransactionException(io.seata.core.exception.TransactionException) GlobalSession(io.seata.server.session.GlobalSession) BranchStatus(io.seata.core.model.BranchStatus) GlobalTransactionEvent(io.seata.core.event.GlobalTransactionEvent) TransactionException(io.seata.core.exception.TransactionException) NotSupportYetException(io.seata.common.exception.NotSupportYetException)

Aggregations

GlobalSession (io.seata.server.session.GlobalSession)73 BranchSession (io.seata.server.session.BranchSession)33 Test (org.junit.jupiter.api.Test)32 Connection (java.sql.Connection)10 TransactionException (io.seata.core.exception.TransactionException)9 ArrayList (java.util.ArrayList)8 SessionCondition (io.seata.server.session.SessionCondition)7 GlobalTransactionEvent (io.seata.core.event.GlobalTransactionEvent)6 BranchStatus (io.seata.core.model.BranchStatus)6 ResultSet (java.sql.ResultSet)6 GlobalTransactionDO (io.seata.core.store.GlobalTransactionDO)5 LockManager (io.seata.server.lock.LockManager)5 FileLockManagerForTest (io.seata.server.lock.file.FileLockManagerForTest)5 FileTransactionStoreManager (io.seata.server.storage.file.store.FileTransactionStoreManager)5 List (java.util.List)5 ParameterizedTest (org.junit.jupiter.params.ParameterizedTest)5 BranchTransactionException (io.seata.core.exception.BranchTransactionException)4 TransactionWriteStore (io.seata.server.storage.file.TransactionWriteStore)4 GlobalStatus (io.seata.core.model.GlobalStatus)3 SessionManager (io.seata.server.session.SessionManager)3