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();
}
}
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();
}
}
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();
}
}
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();
}
}
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;
}
Aggregations