Ver Fonte

调整一下批量操作,增加点警告日志和测试用例.

聂秋秋 há 5 anos atrás
pai
commit
1ae7770d40

+ 6 - 2
mybatis-plus-extension/src/main/java/com/baomidou/mybatisplus/extension/service/impl/ServiceImpl.java

@@ -324,10 +324,14 @@ public class ServiceImpl<M extends BaseMapper<T>, T> implements IService<T> {
         boolean transaction = TransactionSynchronizationManager.isSynchronizationActive();
         if (sqlSessionHolder != null) {
             SqlSession sqlSession = sqlSessionHolder.getSqlSession();
-            //原生无法支持执行器切换,当存在批量操作时,会嵌套两个session的,优先commit上一个session。
-            sqlSession.commit();
+            //原生无法支持执行器切换,当存在批量操作时,会嵌套两个session的,优先commit上一个session
+            //按道理来说,这里的值应该一直为false。
+            sqlSession.commit(!transaction);
         }
         SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
+        if (!transaction) {
+            log.warn("SqlSession [" + sqlSession + "] was not registered for synchronization because DataSource is not transactional");
+        }
         try {
             fun.accept(sqlSession);
             //非事物情况下,强制commit。

+ 1 - 0
mybatis-plus-extension/src/main/java/com/baomidou/mybatisplus/extension/toolkit/SqlHelper.java

@@ -130,6 +130,7 @@ public final class SqlHelper {
      * 批量插入因为无法重用sqlSession,只能新开启一个sqlSession
      *
      * @param clazz 实体类
+     * @deprecated 3.3.1
      */
     @Deprecated
     public static void clearCache(Class<?> clazz) {

+ 22 - 5
mybatis-plus/src/test/java/com/baomidou/mybatisplus/test/h2/H2UserTest.java

@@ -307,13 +307,13 @@ class H2UserTest extends BaseTest {
         Assertions.assertTrue(userService.saveOrUpdateBatch(Arrays.asList(new H2User(1010L, "batch1010"),
             new H2User("batch1011"), new H2User(1010L, "batch1010"), new H2User("batch1015"))));
         Assertions.assertEquals(userService.getById(1010L).getName(), "batch1010");
-        Assertions.assertEquals(userService.count(new QueryWrapper<H2User>().eq("name","batch1011")), 1);
-        Assertions.assertEquals(userService.count(new QueryWrapper<H2User>().eq("name","batch1015")), 1);
+        Assertions.assertEquals(userService.count(new QueryWrapper<H2User>().eq("name", "batch1011")), 1);
+        Assertions.assertEquals(userService.count(new QueryWrapper<H2User>().eq("name", "batch1015")), 1);
         Assertions.assertTrue(userService.saveOrUpdateBatch(Arrays.asList(new H2User(1010L, "batch1010A"),
             new H2User("batch1011AB"), new H2User(1010L, "batch1010"), new H2User("batch1016")), 1));
         Assertions.assertEquals(userService.getById(1010L).getName(), "batch1010");
-        Assertions.assertEquals(userService.count(new QueryWrapper<H2User>().eq("name","batch1011AB")), 1);
-        Assertions.assertEquals(userService.count(new QueryWrapper<H2User>().eq("name","batch1016")), 1);
+        Assertions.assertEquals(userService.count(new QueryWrapper<H2User>().eq("name", "batch1011AB")), 1);
+        Assertions.assertEquals(userService.count(new QueryWrapper<H2User>().eq("name", "batch1016")), 1);
     }
 
     @Test
@@ -387,7 +387,24 @@ class H2UserTest extends BaseTest {
     }
 
     @Test
-    public void myQueryWithGroupByOrderBy() {
+    @Order(30)
+    void testSaveBatchNoTransactional1() {
+        userService.testSaveBatchNoTransactional1();
+        Assertions.assertEquals(3, userService.count(new QueryWrapper<H2User>().like("name", "testSaveBatchNoTransactional1")));
+    }
+
+    @Test
+    @Order(30)
+    void testSaveBatchNoTransactional2() {
+        try {
+            userService.testSaveBatchNoTransactional2();
+        } catch (Exception e) {
+            Assertions.assertEquals(3, userService.count(new QueryWrapper<H2User>().like("name", "testSaveBatchNoTransactional2")));
+        }
+    }
+
+    @Test
+    void myQueryWithGroupByOrderBy() {
         userService.mySelectMaps().forEach(System.out::println);
     }
 

+ 33 - 1
mybatis-plus/src/test/java/com/baomidou/mybatisplus/test/h2/cache/CacheTest.java

@@ -64,7 +64,7 @@ class CacheTest {
         cacheService.save(model);
         cacheService.getById(model.getId());
         cacheService.updateBatchById(Collections.singletonList(new CacheModel(model.getId(), "旺仔")));
-        Assertions.assertEquals(cacheService.getById(model.getId()).getName(),"旺仔");
+        Assertions.assertEquals(cacheService.getById(model.getId()).getName(), "旺仔");
     }
 
     @Test
@@ -90,4 +90,36 @@ class CacheTest {
         CacheModel cacheModel = cacheService.getById(id);
         Assertions.assertEquals(cacheModel.getName(), "小红");
     }
+
+    @Test
+    @Order(6)
+    void testBatchTransactionalClear4() {
+        long id = cacheService.testBatchTransactionalClear4();
+        CacheModel cacheModel = cacheService.getById(id);
+        Assertions.assertEquals(cacheModel.getName(), "旺仔");
+    }
+
+    @Test
+    @Order(7)
+    void testBatchTransactionalClear5() {
+        long id = cacheService.testBatchTransactionalClear5();
+        CacheModel cacheModel = cacheService.getById(id);
+        Assertions.assertNull(cacheModel);
+    }
+
+    @Test
+    @Order(8)
+    void testBatchTransactionalClear6() {
+        long id = cacheService.testBatchTransactionalClear6();
+        CacheModel cacheModel = cacheService.getById(id);
+        Assertions.assertNull(cacheModel);
+    }
+
+    @Test
+    @Order(9)
+    void testBatchTransactionalClear7() {
+        long id = cacheService.testBatchTransactionalClear7();
+        CacheModel cacheModel = cacheService.getById(id);
+        Assertions.assertNull(cacheModel);
+    }
 }

+ 8 - 0
mybatis-plus/src/test/java/com/baomidou/mybatisplus/test/h2/cache/service/ICacheService.java

@@ -10,4 +10,12 @@ public interface ICacheService extends IService<CacheModel> {
     long testBatchTransactionalClear2();
 
     long testBatchTransactionalClear3();
+
+    long testBatchTransactionalClear4();
+
+    long testBatchTransactionalClear5();
+
+    long testBatchTransactionalClear6();
+
+    long testBatchTransactionalClear7();
 }

+ 44 - 0
mybatis-plus/src/test/java/com/baomidou/mybatisplus/test/h2/cache/service/impl/CacheServiceImpl.java

@@ -1,5 +1,6 @@
 package com.baomidou.mybatisplus.test.h2.cache.service.impl;
 
+import com.baomidou.mybatisplus.core.enums.SqlMethod;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.baomidou.mybatisplus.test.h2.cache.mapper.CacheMapper;
 import com.baomidou.mybatisplus.test.h2.cache.model.CacheModel;
@@ -7,11 +8,18 @@ import com.baomidou.mybatisplus.test.h2.cache.service.ICacheService;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
+import java.util.Collection;
 import java.util.Collections;
 
 @Service
 public class CacheServiceImpl extends ServiceImpl<CacheMapper, CacheModel> implements ICacheService {
 
+    //手动撸一个批量删除.
+    private void removeBatchById(Collection<Long> idList) {
+        String sqlStatement = sqlStatement(SqlMethod.DELETE_BY_ID);
+        executeBatch(sqlSession -> idList.forEach(id -> sqlSession.delete(sqlStatement, id)));
+    }
+
     @Override
     @Transactional
     public long testBatchTransactionalClear1() {
@@ -45,4 +53,40 @@ public class CacheServiceImpl extends ServiceImpl<CacheMapper, CacheModel> imple
         getById(model.getId());
         return model.getId();
     }
+
+    @Override
+    public long testBatchTransactionalClear4() {
+        CacheModel model = new CacheModel("靓仔");
+        save(model);
+        updateBatchById(Collections.singletonList(new CacheModel(model.getId(), "旺仔")));
+        return model.getId();
+    }
+
+    @Override
+    public long testBatchTransactionalClear5() {
+        CacheModel model = new CacheModel("靓仔");
+        save(model);
+        removeBatchById(Collections.singletonList(model.getId()));
+        removeById(model.getId());
+        return model.getId();
+    }
+
+    @Override
+    @Transactional
+    public long testBatchTransactionalClear6() {
+        CacheModel model = new CacheModel("靓仔");
+        save(model);
+        removeBatchById(Collections.singletonList(model.getId()));
+        return model.getId();
+    }
+
+    @Override
+    @Transactional
+    public long testBatchTransactionalClear7() {
+        CacheModel model = new CacheModel("靓仔");
+        save(model);
+        updateBatchById(Collections.singletonList(new CacheModel(model.getId(), "旺仔")));
+        removeBatchById(Collections.singletonList(model.getId()));
+        return model.getId();
+    }
 }

+ 4 - 0
mybatis-plus/src/test/java/com/baomidou/mybatisplus/test/h2/service/IH2UserService.java

@@ -53,4 +53,8 @@ public interface IH2UserService extends IService<H2User> {
     void testSaveOrUpdateBatchTransactional();
 
     void testSimpleAndBatchTransactional();
+
+    void testSaveBatchNoTransactional1();
+
+    void testSaveBatchNoTransactional2();
 }

+ 12 - 0
mybatis-plus/src/test/java/com/baomidou/mybatisplus/test/h2/service/impl/H2UserServiceImpl.java

@@ -123,4 +123,16 @@ public class H2UserServiceImpl extends ServiceImpl<H2UserMapper, H2User> impleme
         saveOrUpdateBatch(Arrays.asList(new H2User("simpleAndBatchTx5", 0), new H2User("simpleAndBatchTx6", 0), new H2User("simpleAndBatchTx7", 0)), 1);
         throw new MybatisPlusException("测试事务回滚");
     }
+
+    @Override
+    public void testSaveBatchNoTransactional1() {
+        saveBatch(Arrays.asList(new H2User("testSaveBatchNoTransactional1", 0), new H2User("testSaveBatchNoTransactional1", 0), new H2User("testSaveBatchNoTransactional1", 0)), 1);
+    }
+
+    @Override
+    public void testSaveBatchNoTransactional2() {
+        //非事物下,制造一个批量主键冲突
+        save(new H2User(1577431655447L, "testSaveBatchNoTransactional2"));
+        saveBatch(Arrays.asList(new H2User("testSaveBatchNoTransactional2", 0), new H2User("testSaveBatchNoTransactional2", 0), new H2User(1577431655447L, "testSaveBatchNoTransactional2")), 1);
+    }
 }