diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/optimisticlock/OptimisticLockManager.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/optimisticlock/OptimisticLockManager.java new file mode 100644 index 00000000..63504c8a --- /dev/null +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/optimisticlock/OptimisticLockManager.java @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2022-2025, Mybatis-Flex (fuhai999@gmail.com). + *

+ * 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 com.mybatisflex.core.optimisticlock; + +import java.util.function.Supplier; + +/** + * 乐观锁管理器。 + */ +public class OptimisticLockManager { + + private OptimisticLockManager() { + } + + private static final ThreadLocal skipFlags = new ThreadLocal<>(); + + /** + * 跳过乐观锁字段处理,直接进行数据库物理操作。 + */ + public static T execWithoutOptimisticLock(Supplier supplier) { + try { + skipOptimisticLock(); + return supplier.get(); + } finally { + restoreOptimisticLock(); + } + } + + /** + * 跳过乐观锁字段处理,直接进行数据库物理操作。 + */ + public static void execWithoutOptimisticLock(Runnable runnable) { + try { + skipOptimisticLock(); + runnable.run(); + } finally { + restoreOptimisticLock(); + } + } + + /** + * 跳过乐观锁字段处理。 + */ + public static void skipOptimisticLock() { + skipFlags.set(Boolean.TRUE); + } + + /** + * 恢复乐观锁字段处理。 + */ + public static void restoreOptimisticLock() { + skipFlags.remove(); + } + + /** + * 获取乐观锁列,返回 {@code null} 表示跳过乐观锁。 + * + * @param optimisticLockColumn 乐观锁列 + * @return 乐观锁列 + */ + public static String getOptimisticLockColumn(String optimisticLockColumn) { + if (optimisticLockColumn == null) { + return null; + } + Boolean skipFlag = skipFlags.get(); + if (skipFlag == null) { + return optimisticLockColumn; + } + return skipFlag ? null : optimisticLockColumn; + } + +} diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/optimisticlock/package-info.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/optimisticlock/package-info.java new file mode 100644 index 00000000..c959260b --- /dev/null +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/optimisticlock/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2022-2025, Mybatis-Flex (fuhai999@gmail.com). + *

+ * 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 com.mybatisflex.core.optimisticlock; diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/table/TableInfo.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/table/TableInfo.java index 5515e0e1..07d0987a 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/table/TableInfo.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/table/TableInfo.java @@ -30,6 +30,7 @@ import com.mybatisflex.core.exception.FlexExceptions; import com.mybatisflex.core.exception.locale.LocalizedFormats; import com.mybatisflex.core.logicdelete.LogicDeleteManager; import com.mybatisflex.core.mybatis.TypeHandlerObject; +import com.mybatisflex.core.optimisticlock.OptimisticLockManager; import com.mybatisflex.core.query.Brackets; import com.mybatisflex.core.query.CPI; import com.mybatisflex.core.query.Join; @@ -241,6 +242,10 @@ public class TableInfo { this.logicDeleteColumn = logicDeleteColumn; } + public String getOptimisticLockColumnOrSkip() { + return OptimisticLockManager.getOptimisticLockColumn(versionColumn); + } + public String getVersionColumn() { return versionColumn; } @@ -884,7 +889,7 @@ public class TableInfo { } // 添加乐观锁条件,只有在 update 的时候进行处理 - if (StringUtil.isNotBlank(versionColumn) && entity != null) { + if (StringUtil.isNotBlank(getOptimisticLockColumnOrSkip()) && entity != null) { Object versionValue = buildColumnSqlArg(entity, versionColumn); if (versionValue == null) { throw FlexExceptions.wrap(LocalizedFormats.ENTITY_VERSION_NULL, entity);