001/* 002 * Copyright (c) 2022-2023, Mybatis-Flex (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 com.mybatisflex.spring; 017 018import com.mybatisflex.core.transaction.TransactionContext; 019import com.mybatisflex.core.transaction.TransactionalManager; 020import com.mybatisflex.core.util.StringUtil; 021import org.springframework.transaction.TransactionDefinition; 022import org.springframework.transaction.TransactionException; 023import org.springframework.transaction.support.AbstractPlatformTransactionManager; 024import org.springframework.transaction.support.DefaultTransactionStatus; 025 026/** 027 * MyBatis-Flex 事务支持。 028 * @author michael 029 */ 030public class FlexTransactionManager extends AbstractPlatformTransactionManager { 031 032 @Override 033 protected Object doGetTransaction() throws TransactionException { 034 return new TransactionObject(TransactionContext.getXID()); 035 } 036 037 @Override 038 protected boolean isExistingTransaction(Object transaction) throws TransactionException { 039 TransactionObject transactionObject = (TransactionObject) transaction; 040 return StringUtil.isNotBlank(transactionObject.prevXid); 041 } 042 043 @Override 044 protected Object doSuspend(Object transaction) throws TransactionException { 045 TransactionContext.release(); 046 TransactionObject transactionObject = (TransactionObject) transaction; 047 return transactionObject.prevXid; 048 } 049 050 @Override 051 protected void doResume(Object transaction, Object suspendedResources) throws TransactionException { 052 String xid = (String) suspendedResources; 053 TransactionContext.holdXID(xid); 054 } 055 056 @Override 057 protected void doBegin(Object transaction, TransactionDefinition definition) throws TransactionException { 058 TransactionObject transactionObject = (TransactionObject) transaction; 059 transactionObject.currentXid = TransactionalManager.startTransactional(); 060 } 061 062 @Override 063 protected void doCommit(DefaultTransactionStatus status) throws TransactionException { 064 TransactionObject transactionObject = (TransactionObject) status.getTransaction(); 065 TransactionalManager.commit(transactionObject.currentXid); 066 } 067 068 @Override 069 protected void doRollback(DefaultTransactionStatus status) throws TransactionException { 070 TransactionObject transactionObject = (TransactionObject) status.getTransaction(); 071 TransactionalManager.rollback(transactionObject.currentXid); 072 } 073 074 @Override 075 protected void doSetRollbackOnly(DefaultTransactionStatus status) throws TransactionException { 076 // 在多个事务嵌套时,子事务的传递方式为 REQUIRED(加入当前事务) 077 // 那么,当子事务抛出异常时,会调当前方法,而不是直接调用 doRollback 078 // 此时,不需要做任何处理即可,默认上父级事务进行正常 doRollback 即可。 079 } 080 081 082 static class TransactionObject { 083 084 private final String prevXid; 085 private String currentXid; 086 087 public TransactionObject(String prevXid) { 088 this.prevXid = prevXid; 089 } 090 091 } 092 093}