transaction 事务 开启 关闭 不使用 手动控制 spring springboot mybatis

比眉伴天荒 2024-02-22 09:11 109阅读 0赞

spring springboot mybatis 事务配置 Transactional的Propagation 开启事务 关闭事务_globalcoding

省流:

单元测试时,发现默认是使用事务。想要关闭事务,使用:

  1. @Transactional(propagation = Propagation.NOT_SUPPORTED)

正文:

默认是使用事务

做单元测试的时候,发现默认是使用事务的。代码和日志如下:

  1. @RunWith(SpringRunner.class)
  2. @MybatisPlusTest
  3. @AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
  4. @Rollback(false)
  5. public class T1 {
  6. @Autowired
  7. private XxxMapper xxxMapper;
  8. @Test
  9. public void t1() {
  10. int i = 0;
  11. List<XxxDo> xxxDoList = getData();
  12. System.out.println("我的打印:插入数量 count:" + xxxDoList.size());
  13. for (XxxDo o : xxxDoList) {
  14. XxxDo existed = xxxMapper.selectOne(new LambdaQueryWrapper<XxxDo>()
  15. .eq(XxxDo::getId,o.getId()));
  16. if(null != existed){continue;}
  17. xxxMapper.insert(o);
  18. if(i==100){
  19. int a = 1/0;
  20. }
  21. i++;
  22. }
  23. System.out.println("我的打印:循环插入结束");
  24. }
  25. public List<XxxDo> getData(){
  26. ....
  27. return list;
  28. }
  29. }

日志:

  1. _ _ |_ _ _|_. ___ _ | _
  2. | | |\/|_)(_| | |_\ |_)||_|_\
  3. / |
  4. 3.3.0
  5. INFO 12-10-2023 07:39:41.014 main Started T1 in 13.452 seconds (JVM running for 17.662)
  6. INFO 12-10-2023 07:39:41.297 main {dataSource-1} inited
  7. INFO 12-10-2023 07:39:41.652 main Began transaction (1) for test context [DefaultTestContext@5a8c93 testClass = T1, testInstance = com.ali.cloud.test.T1@3bed3315, testMethod = t1@T1, testException = [null], mergedContextConfiguration = [MergedContextConfiguration@119b0892 testClass = T1, locations = '{}', classes = '{class com.ali.cloud.Application}', contextInitializerClasses = '[]', activeProfiles = '{}', propertySourceLocations = '{}', propertySourceProperties = '{com.baomidou.mybatisplus.test.autoconfigure.MybatisPlusTestContextBootstrapper=true}', contextCustomizers = set[[ImportsContextCustomizer@1a3e8e24 key = [org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration, org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration, org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration, org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration, org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration, org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration, org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration, com.baomidou.mybatisplus.autoconfigure.MybatisPlusLanguageDriverAutoConfiguration, com.baomidou.mybatisplus.autoconfigure.MybatisPlusAutoConfiguration, org.springframework.boot.test.autoconfigure.jdbc.TestDatabaseAutoConfiguration]], org.springframework.boot.test.context.filter.ExcludeFilterContextCustomizer@20d525, org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer@69453e37, org.springframework.boot.test.mock.mockito.MockitoContextCustomizer@0, org.springframework.boot.test.autoconfigure.OverrideAutoConfigurationContextCustomizerFactory$DisableAutoConfigurationContextCustomizer@4961f6af, org.springframework.boot.test.autoconfigure.filter.TypeExcludeFiltersContextCustomizer@351584c0, org.springframework.boot.test.autoconfigure.properties.PropertyMappingContextCustomizer@f1c9823f, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverContextCustomizerFactory$Customizer@4c309d4d], contextLoader = 'org.springframework.boot.test.context.SpringBootContextLoader', parent = [null]], attributes = map[[empty]]]; transaction manager [org.springframework.jdbc.datasource.DataSourceTransactionManager@4ed4a7e4]; rollback [false]
  8. 我的打印:插入数量 count: 2000
  9. Creating a new SqlSession
  10. Registering transaction synchronization for SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@2e62ead7]
  11. JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@63f6bed1] will be managed by Spring
  12. ==> Preparing: SELECT xxx from xxx where xxx
  13. ==> Parameters: 4444b1e53dxxx0d09bcaaa0c6362ayyy(String), 1234b1e53dxxx0d09bcaaa0c6362axxx(String), 0(Integer)
  14. <== Total: 0
  15. Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@2e62ead7]
  16. Fetched SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@2e62ead7] from current transaction
  17. ==> Preparing: INSERT INTO xxx( xxx ) VALUES ( ?, ?, ?, ?, ?, ? )
  18. ==> Parameters: 2342251622094285111(String),xxx, 2023-10-12 07:39:42.762(Timestamp), global_coding(String), 2023-10-12 07:39:42.762(Timestamp), global_coding(String)
  19. <== Updates: 1
  20. Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@2e62ead7]
  21. Fetched SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@2e62ead7] from current transaction
  22. ==> Preparing: INSERT INTO xxx( xxx ) VALUES ( ?, ?, ?, ?, ?, ? )
  23. ==> Parameters: 2342251622094285112(String),xxx, 2023-10-12 07:39:42.762(Timestamp), global_coding(String), 2023-10-12 07:39:42.762(Timestamp), global_coding(String)
  24. <== Updates: 1
  25. 我的打印:循环插入结束
  26. Transaction synchronization committing SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@2e62ead7]
  27. Transaction synchronization deregistering SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@2e62ead7]
  28. Transaction synchronization closing SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@2e62ead7]
  29. INFO 12-10-2023 07:40:10.436 main Committed transaction for test: [DefaultTestContext@5a8c93 testClass = T1, testInstance = com.ali.cloud.test.T1@3bed3315, testMethod = t1@T1, testException = java.lang.ArithmeticException: / by zero, mergedContextConfiguration = [MergedContextConfiguration@119b0892 testClass = T1, locations = '{}', classes = '{class com.ali.cloud.Application}', contextInitializerClasses = '[]', activeProfiles = '{}', propertySourceLocations = '{}', propertySourceProperties = '{com.baomidou.mybatisplus.test.autoconfigure.MybatisPlusTestContextBootstrapper=true}', contextCustomizers = set[[ImportsContextCustomizer@1a3e8e24 key = [org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration, org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration, org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration, org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration, org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration, org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration, org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration, com.baomidou.mybatisplus.autoconfigure.MybatisPlusLanguageDriverAutoConfiguration, com.baomidou.mybatisplus.autoconfigure.MybatisPlusAutoConfiguration, org.springframework.boot.test.autoconfigure.jdbc.TestDatabaseAutoConfiguration]], org.springframework.boot.test.context.filter.ExcludeFilterContextCustomizer@20d525, org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer@69453e37, org.springframework.boot.test.mock.mockito.MockitoContextCustomizer@0, org.springframework.boot.test.autoconfigure.OverrideAutoConfigurationContextCustomizerFactory$DisableAutoConfigurationContextCustomizer@4961f6af, org.springframework.boot.test.autoconfigure.filter.TypeExcludeFiltersContextCustomizer@351584c0, org.springframework.boot.test.autoconfigure.properties.PropertyMappingContextCustomizer@f1c9823f, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverContextCustomizerFactory$Customizer@4c309d4d], contextLoader = 'org.springframework.boot.test.context.SpringBootContextLoader', parent = [null]], attributes = map[[empty]]]
  30. INFO 12-10-2023 07:40:10.455 SpringContextShutdownHook {dataSource-1} closing ...
  31. INFO 12-10-2023 07:40:10.463 SpringContextShutdownHook {dataSource-1} closed

通过日志发现,默认用了事务transaction,这会有一个现象,就是在事务结束前,所有的insert是没有commit的。也就是必须得等到程序结束,数据库才会有数据存进去。

并且,还发现,如果中间出现异常,异常之前的数据是会提交到数据库。

实验:在程序跑起来,循环insert的时候,去查询数据库,是查不到这些数据的。

关闭事务

如果想要插入一条,数据库就有一条,只需要不使用事务即可。关闭事务的方式是:在方法上加上如下注解:

  1. @Transactional(propagation = Propagation.NOT_SUPPORTED)

  1. @Test
  2. @Transactional(propagation = Propagation.NOT_SUPPORTED)
  3. public void t1() {
  4. int i = 0;
  5. List<XxxDo> xxxDoList = getData();
  6. System.out.println("我的打印:插入数量 count:" + xxxDoList.size());
  7. for (XxxDo o : xxxDoList) {
  8. XxxDo existed = xxxMapper.selectOne(new LambdaQueryWrapper<XxxDo>()
  9. .eq(XxxDo::getId,o.getId()));
  10. if(null != existed){continue;}
  11. xxxMapper.insert(o);
  12. if(i==100){
  13. int a = 1/0;
  14. }
  15. i++;
  16. }
  17. System.out.println("我的打印:循环插入结束");
  18. }

日志如下:

  1. _ _ |_ _ _|_. ___ _ | _
  2. | | |\/|_)(_| | |_\ |_)||_|_\
  3. / |
  4. 3.3.0
  5. INFO 13-10-2023 09:37:55.641 main Started T1 in 13.353 seconds (JVM running for 16.686)
  6. 我的打印 count: 2293
  7. Creating a new SqlSession
  8. SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@37348491] was not registered for synchronization because synchronization is not active
  9. INFO 13-10-2023 09:37:56.937 main {dataSource-1} inited
  10. JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@259b85d6] will not be managed by Spring
  11. ==> Preparing: SELECT xxx from xxx where xxx
  12. ==> Parameters: 5555b1e53dxxx0d09bcaaa0c6362ayyy(String), 1234b1e53dxxx0d09bcaaa0c6362axxx(String), 0(Integer)
  13. <== Total: 0
  14. Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@37348491]
  15. Creating a new SqlSession
  16. SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@66bf40e5] was not registered for synchronization because synchronization is not active
  17. JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@259b85d6] will not be managed by Spring
  18. ==> Preparing: INSERT INTO xxx( xxx ) VALUES ( ?, ?, ?, ?, ?, ? )
  19. ==> Parameters: 2342251622094285111(String),xxx, 2023-10-12 07:39:42.762(Timestamp), global_coding(String), 2023-10-12 07:39:42.762(Timestamp), global_coding(String)
  20. <== Updates: 1
  21. Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@66bf40e5]
  22. Creating a new SqlSession
  23. SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@5a515e5d] was not registered for synchronization because synchronization is not active
  24. JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@259b85d6] will not be managed by Spring
  25. ==> Preparing: SELECT xxx from xxx where xxx
  26. ==> Parameters: 5555b1e53dxxx0d09bcaaa0c6362ayyy(String), 1234b1e53dxxx0d09bcaaa0c6362axxx(String), 0(Integer)
  27. <== Total: 0
  28. Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@5a515e5d]
  29. Creating a new SqlSession
  30. SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@32f32623] was not registered for synchronization because synchronization is not active
  31. JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@259b85d6] will not be managed by Spring
  32. ==> Preparing: INSERT INTO xxx( xxx ) VALUES ( ?, ?, ?, ?, ?, ? )
  33. ==> Parameters: 2342251622094285111(String),xxx, 2023-10-12 07:39:42.762(Timestamp), global_coding(String), 2023-10-12 07:39:42.762(Timestamp), global_coding(String)
  34. <== Updates: 1
  35. Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@32f32623]
  36. 我的打印:循环插入结束
  37. INFO 13-10-2023 09:38:00.505 SpringContextShutdownHook {dataSource-1} closing ...
  38. INFO 13-10-2023 09:38:00.512 SpringContextShutdownHook {dataSource-1} closed

根据两个日志对比,最明显的区别是开启事务的方法只创建了一个SqlSession,没开启事务的方法每一次执行sql都会创建一个SqlSession。

日志里是这句话:Creating a new SqlSession

若开启事务,处理SqlSession的步骤:释放SqlSession,再获取SqlSession,再去执行sql。

若关闭事务,处理SqlSession的步骤:关闭SqlSession,再创建SqlSession,再去执行sql。

当然,还有更具体的细节:

1. 开始都会先初始化数据源,最后都会关闭数据源。

日志:

{dataSource-1} inited,{dataSource-1} closing …,{dataSource-1} closed

2. jdbc connection都用的是同一个,但两处日志不一样,一个是交给spring管理,一个是没交给spring管理。

日志:

JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@63f6bed1] will be managed by Spring

JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@259b85d6] will not be managed by Spring

手动控制事务

单独对某句sql做一个事务,即手动控制事务。

增加如下4行代码

  1. DefaultTransactionDefinition dt = new DefaultTransactionDefinition();
  2. dt.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
  3. TransactionStatus status = platformTransactionManager.getTransaction(dt);
  4. platformTransactionManager.commit(status);

用法是:包裹住执行sql语句即可。

  1. DefaultTransactionDefinition dt = new DefaultTransactionDefinition();
  2. dt.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
  3. TransactionStatus status = platformTransactionManager.getTransaction(dt);
  4. mapper.insert(o);
  5. platformTransactionManager.commit(status);

这是将查询和插入都包裹住的日志:

  1. @Autowired
  2. private PlatformTransactionManager platformTransactionManager;
  3. @Test
  4. public void t1(){
  5. for(int i=0; i<list.size(); i++){
  6. DefaultTransactionDefinition dt = new DefaultTransactionDefinition();
  7. dt.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
  8. TransactionStatus status = platformTransactionManager.getTransaction(dt);
  9. mapper.select(o);
  10. mapper.insert(o);
  11. platformTransactionManager.commit(status);
  12. }
  13. }
  14. _ _ |_ _ _|_. ___ _ | _
  15. | | |\/|_)(_| | |_\ |_)||_|_\
  16. / |
  17. 3.3.0
  18. INFO 13-10-2023 17:53:24.989 main Started T1 in 12.882 seconds (JVM running for 16.576)
  19. INFO 13-10-2023 17:53:25.302 main {dataSource-1} inited
  20. INFO 13-10-2023 17:53:25.682 main Began transaction (1) for test context [DefaultTestContext@4ed4a7e4 testClass = T1, testInstance = com.ali.cloud.iot.T1@1c7350b0, testMethod = t1@T1, testException = [null], mergedContextConfiguration = [MergedContextConfiguration@55651434 testClass = T1, locations = '{}', classes = '{class com.ali.cloud.Application}', contextInitializerClasses = '[]', activeProfiles = '{}', propertySourceLocations = '{}', propertySourceProperties = '{com.baomidou.mybatisplus.test.autoconfigure.MybatisPlusTestContextBootstrapper=true}', contextCustomizers = set[[ImportsContextCustomizer@3bc4ef12 key = [org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration, org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration, org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration, org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration, org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration, org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration, org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration, com.baomidou.mybatisplus.autoconfigure.MybatisPlusLanguageDriverAutoConfiguration, com.baomidou.mybatisplus.autoconfigure.MybatisPlusAutoConfiguration, org.springframework.boot.test.autoconfigure.jdbc.TestDatabaseAutoConfiguration]], org.springframework.boot.test.context.filter.ExcludeFilterContextCustomizer@587e5365, org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer@63475ace, org.springframework.boot.test.mock.mockito.MockitoContextCustomizer@0, org.springframework.boot.test.autoconfigure.OverrideAutoConfigurationContextCustomizerFactory$DisableAutoConfigurationContextCustomizer@291caca8, org.springframework.boot.test.autoconfigure.filter.TypeExcludeFiltersContextCustomizer@351584c0, org.springframework.boot.test.autoconfigure.properties.PropertyMappingContextCustomizer@44ef74f7, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverContextCustomizerFactory$Customizer@38e79ae3], contextLoader = 'org.springframework.boot.test.context.SpringBootContextLoader', parent = [null]], attributes = map[[empty]]]; transaction manager [org.springframework.jdbc.datasource.DataSourceTransactionManager@50448409]; rollback [false]
  21. 我的打印 count: 2293
  22. Creating a new SqlSession
  23. Registering transaction synchronization for SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@32faa16c]
  24. JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@6ea246af] will be managed by Spring
  25. ==> Preparing: SELECT xxx
  26. ==> Parameters: xxx
  27. <== Total: 0
  28. Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@32faa16c]
  29. Fetched SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@32faa16c] from current transaction
  30. ==> Preparing: INSERT INTO xxx
  31. ==> Parameters: xxx
  32. <== Updates: 1
  33. Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@32faa16c]
  34. Transaction synchronization committing SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@32faa16c]
  35. Transaction synchronization deregistering SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@32faa16c]
  36. Transaction synchronization closing SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@32faa16c]
  37. Creating a new SqlSession
  38. Registering transaction synchronization for SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@7e1ffe70]
  39. JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@6ea246af] will be managed by Spring
  40. ==> Preparing: SELECT xxx
  41. ==> Parameters: xxx
  42. <== Total: 0
  43. Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@7e1ffe70]
  44. Fetched SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@7e1ffe70] from current transaction
  45. ==> Preparing: INSERT INTO xxx
  46. ==> Parameters: xxx
  47. <== Updates: 1
  48. Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@7e1ffe70]
  49. Transaction synchronization committing SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@7e1ffe70]
  50. Transaction synchronization deregistering SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@7e1ffe70]
  51. Transaction synchronization closing SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@7e1ffe70]
  52. 我的打印:循环插入结束
  53. INFO 13-10-2023 17:53:29.971 main Committed transaction for test: [DefaultTestContext@4ed4a7e4 testClass = T1, testInstance = com.ali.cloud.iot.T1@1c7350b0, testMethod = t1@T1, testException = [null], mergedContextConfiguration = [MergedContextConfiguration@55651434 testClass = T1, locations = '{}', classes = '{class com.ali.cloud.Application}', contextInitializerClasses = '[]', activeProfiles = '{}', propertySourceLocations = '{}', propertySourceProperties = '{com.baomidou.mybatisplus.test.autoconfigure.MybatisPlusTestContextBootstrapper=true}', contextCustomizers = set[[ImportsContextCustomizer@3bc4ef12 key = [org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration, org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration, org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration, org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration, org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration, org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration, org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration, com.baomidou.mybatisplus.autoconfigure.MybatisPlusLanguageDriverAutoConfiguration, com.baomidou.mybatisplus.autoconfigure.MybatisPlusAutoConfiguration, org.springframework.boot.test.autoconfigure.jdbc.TestDatabaseAutoConfiguration]], org.springframework.boot.test.context.filter.ExcludeFilterContextCustomizer@587e5365, org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer@63475ace, org.springframework.boot.test.mock.mockito.MockitoContextCustomizer@0, org.springframework.boot.test.autoconfigure.OverrideAutoConfigurationContextCustomizerFactory$DisableAutoConfigurationContextCustomizer@291caca8, org.springframework.boot.test.autoconfigure.filter.TypeExcludeFiltersContextCustomizer@351584c0, org.springframework.boot.test.autoconfigure.properties.PropertyMappingContextCustomizer@44ef74f7, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverContextCustomizerFactory$Customizer@38e79ae3], contextLoader = 'org.springframework.boot.test.context.SpringBootContextLoader', parent = [null]], attributes = map[[empty]]]
  54. INFO 13-10-2023 17:53:29.982 SpringContextShutdownHook {dataSource-1} closing ...
  55. INFO 13-10-2023 17:53:29.993 SpringContextShutdownHook {dataSource-1} closed

这是查询在外面,单独包裹住插入的日志:

  1. for(int i=0; i<list.size(); i++){
  2. mapper.select(o);
  3. DefaultTransactionDefinition dt = new DefaultTransactionDefinition();
  4. dt.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
  5. TransactionStatus status = platformTransactionManager.getTransaction(dt);
  6. mapper.insert(o);
  7. platformTransactionManager.commit(status);
  8. }
  9. _ _ |_ _ _|_. ___ _ | _
  10. | | |\/|_)(_| | |_\ |_)||_|_\
  11. / |
  12. 3.3.0
  13. INFO 13-10-2023 18:58:43.950 main Started T1 in 18.362 seconds (JVM running for 22.704)
  14. INFO 13-10-2023 18:58:44.356 main {dataSource-1} inited
  15. INFO 13-10-2023 18:58:45.206 main Began transaction (1) for test context [DefaultTestContext@1a3e8e24 testClass = T1, testInstance = com.ali.cloud.iot.T1@4ed4a7e4, testMethod = t1@T1, testException = [null], mergedContextConfiguration = [MergedContextConfiguration@1c7350b0 testClass = T1, locations = '{}', classes = '{class com.ali.cloud.Application}', contextInitializerClasses = '[]', activeProfiles = '{}', propertySourceLocations = '{}', propertySourceProperties = '{com.baomidou.mybatisplus.test.autoconfigure.MybatisPlusTestContextBootstrapper=true}', contextCustomizers = set[[ImportsContextCustomizer@55651434 key = [org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration, org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration, org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration, org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration, org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration, org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration, org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration, com.baomidou.mybatisplus.autoconfigure.MybatisPlusLanguageDriverAutoConfiguration, com.baomidou.mybatisplus.autoconfigure.MybatisPlusAutoConfiguration, org.springframework.boot.test.autoconfigure.jdbc.TestDatabaseAutoConfiguration]], org.springframework.boot.test.context.filter.ExcludeFilterContextCustomizer@587e5365, org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer@63475ace, org.springframework.boot.test.mock.mockito.MockitoContextCustomizer@0, org.springframework.boot.test.autoconfigure.OverrideAutoConfigurationContextCustomizerFactory$DisableAutoConfigurationContextCustomizer@291caca8, org.springframework.boot.test.autoconfigure.filter.TypeExcludeFiltersContextCustomizer@351584c0, org.springframework.boot.test.autoconfigure.properties.PropertyMappingContextCustomizer@44ef74f7, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverContextCustomizerFactory$Customizer@38e79ae3], contextLoader = 'org.springframework.boot.test.context.SpringBootContextLoader', parent = [null]], attributes = map[[empty]]]; transaction manager [org.springframework.jdbc.datasource.DataSourceTransactionManager@3bc4ef12]; rollback [false]
  16. 我的打印:count: 2293
  17. Creating a new SqlSession
  18. Registering transaction synchronization for SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@16da476c]
  19. JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@29fe4840] will be managed by Spring
  20. ==> Preparing: SELECT xxxx
  21. ==> Parameters: xxx
  22. <== Total: 0
  23. Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@16da476c]
  24. Transaction synchronization suspending SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@16da476c]
  25. Creating a new SqlSession
  26. Registering transaction synchronization for SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@7b25ab31]
  27. JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@494c8f29] will be managed by Spring
  28. ==> Preparing: INSERT INTO xxx
  29. ==> Parameters: xxx
  30. <== Updates: 1
  31. Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@7b25ab31]
  32. Transaction synchronization committing SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@7b25ab31]
  33. Transaction synchronization deregistering SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@7b25ab31]
  34. Transaction synchronization closing SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@7b25ab31]
  35. Transaction synchronization resuming SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@16da476c]
  36. Fetched SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@16da476c] from current transaction
  37. ==> Preparing: SELECT xxx
  38. ==> Parameters: xxx
  39. <== Total: 0
  40. Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@16da476c]
  41. Transaction synchronization suspending SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@16da476c]
  42. Creating a new SqlSession
  43. Registering transaction synchronization for SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@574059d5]
  44. JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@494c8f29] will be managed by Spring
  45. ==> Preparing: INSERT INTO xxx
  46. ==> Parameters: xxx
  47. <== Updates: 1
  48. Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@574059d5]
  49. Transaction synchronization committing SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@574059d5]
  50. Transaction synchronization deregistering SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@574059d5]
  51. Transaction synchronization closing SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@574059d5]
  52. Transaction synchronization resuming SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@16da476c]
  53. 我的打印:循环插入结束
  54. Transaction synchronization committing SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@16da476c]
  55. Transaction synchronization deregistering SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@16da476c]
  56. Transaction synchronization closing SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@16da476c]
  57. INFO 13-10-2023 18:58:50.166 main Committed transaction for test: [DefaultTestContext@1a3e8e24 testClass = T1, testInstance = com.ali.cloud.iot.T1@4ed4a7e4, testMethod = t1@T1, testException = [null], mergedContextConfiguration = [MergedContextConfiguration@1c7350b0 testClass = T1, locations = '{}', classes = '{class com.ali.cloud.Application}', contextInitializerClasses = '[]', activeProfiles = '{}', propertySourceLocations = '{}', propertySourceProperties = '{com.baomidou.mybatisplus.test.autoconfigure.MybatisPlusTestContextBootstrapper=true}', contextCustomizers = set[[ImportsContextCustomizer@55651434 key = [org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration, org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration, org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration, org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration, org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration, org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration, org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration, com.baomidou.mybatisplus.autoconfigure.MybatisPlusLanguageDriverAutoConfiguration, com.baomidou.mybatisplus.autoconfigure.MybatisPlusAutoConfiguration, org.springframework.boot.test.autoconfigure.jdbc.TestDatabaseAutoConfiguration]], org.springframework.boot.test.context.filter.ExcludeFilterContextCustomizer@587e5365, org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer@63475ace, org.springframework.boot.test.mock.mockito.MockitoContextCustomizer@0, org.springframework.boot.test.autoconfigure.OverrideAutoConfigurationContextCustomizerFactory$DisableAutoConfigurationContextCustomizer@291caca8, org.springframework.boot.test.autoconfigure.filter.TypeExcludeFiltersContextCustomizer@351584c0, org.springframework.boot.test.autoconfigure.properties.PropertyMappingContextCustomizer@44ef74f7, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverContextCustomizerFactory$Customizer@38e79ae3], contextLoader = 'org.springframework.boot.test.context.SpringBootContextLoader', parent = [null]], attributes = map[[empty]]]
  58. INFO 13-10-2023 18:58:50.179 SpringContextShutdownHook {dataSource-1} closing ...
  59. INFO 13-10-2023 18:58:50.190 SpringContextShutdownHook {dataSource-1} closed

根据日志,两种区别是:

第2种没有将查询包裹的,他是从事务中取出的session,fetched sqlsession from transaction,被包裹住的那个插入语句他是重新创建的session,creating a new sqlsession。

也就是说代码执行逻辑是这样:进入for循环->创建sqlsession1,执行查询sql,释放sqlsession1,挂起sqlsession1->进入到独立手动控制事务的代码->创建sqlsession2-,执行插入sql,释放、提交、注销、关闭sqlsession2,恢复sqlsession1->取出sqlsession1,执行查询sql,释放sqlsession1,挂起sqlsession1->…最后执行完了,走出for循环,执行其他代码,走出方法,提交、注销、关闭sqlsession1->关闭datasource

======================分割线==========================

文章到此已经结束,以下是紫薯布丁

@RunWith(SpringRunner.class)
@MybatisPlusTest
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
@Rollback(false)
public class T1 {

@Autowired
private XxxMapper xxxMapper;

@Test

@Transactional(propagation = Propagation.NOT_SUPPORTED)
public void t1() {
int i = 0;
List xxxDoList = getData();
System.out.println(“我的打印:插入数量 count:” + xxxDoList.size());
for (XxxDo o : xxxDoList) {
XxxDo existed = xxxMapper.selectOne(new LambdaQueryWrapper()
.eq(XxxDo::getId,o.getId()));
if(null != existed){continue;}
xxxMapper.insert(o);
if(i==100){
int a = 1/0;
}
i++;
}
System.out.println(“我的打印:循环插入结束”);
}

public List getData(){
….
return list;
}

}

_ _ |_ _ _|_. ___ _ | _
| | |\/|_)(_| | |_\ |_)||_|_\
/ |
3.3.0
INFO 12-10-2023 07:39:41.014 main Started T1 in 13.452 seconds (JVM running for 17.662)
INFO 12-10-2023 07:39:41.297 main {dataSource-1} inited
INFO 12-10-2023 07:39:41.652 main Began transaction (1) for test context [DefaultTestContext@5a8c93 testClass = T1, testInstance = com.ali.cloud.test.T1@3bed3315, testMethod = t1@T1, testException = [null], mergedContextConfiguration = [MergedContextConfiguration@119b0892 testClass = T1, locations = ‘{}‘, classes = ‘{class com.ali.cloud.Application}‘, contextInitializerClasses = ‘[]‘, activeProfiles = ‘{}‘, propertySourceLocations = ‘{}‘, propertySourceProperties = ‘{com.baomidou.mybatisplus.test.autoconfigure.MybatisPlusTestContextBootstrapper=true}‘, contextCustomizers = set[[ImportsContextCustomizer@1a3e8e24 key = [org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration, org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration, org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration, org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration, org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration, org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration, org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration, com.baomidou.mybatisplus.autoconfigure.MybatisPlusLanguageDriverAutoConfiguration, com.baomidou.mybatisplus.autoconfigure.MybatisPlusAutoConfiguration, org.springframework.boot.test.autoconfigure.jdbc.TestDatabaseAutoConfiguration]], org.springframework.boot.test.context.filter.ExcludeFilterContextCustomizer@20d525, org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer@69453e37, org.springframework.boot.test.mock.mockito.MockitoContextCustomizer@0, org.springframework.boot.test.autoconfigure.OverrideAutoConfigurationContextCustomizerFactory$DisableAutoConfigurationContextCustomizer@4961f6af, org.springframework.boot.test.autoconfigure.filter.TypeExcludeFiltersContextCustomizer@351584c0, org.springframework.boot.test.autoconfigure.properties.PropertyMappingContextCustomizer@f1c9823f, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverContextCustomizerFactory$Customizer@4c309d4d], contextLoader = ‘org.springframework.boot.test.context.SpringBootContextLoader’, parent = [null]], attributes = map[[empty]]]; transaction manager [org.springframework.jdbc.datasource.DataSourceTransactionManager@4ed4a7e4]; rollback [false]
我的打印:插入数量 count: 2000
Creating a new SqlSession
Registering transaction synchronization for SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@2e62ead7]
JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@63f6bed1] will be managed by Spring
==> Preparing: SELECT xxx from xxx where xxx
==> Parameters: 4444b1e53dxxx0d09bcaaa0c6362ayyy(String), 1234b1e53dxxx0d09bcaaa0c6362axxx(String), 0(Integer)
<== Total: 0
Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@2e62ead7]
Fetched SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@2e62ead7] from current transaction
==> Preparing: INSERT INTO xxx( xxx ) VALUES ( ?, ?, ?, ?, ?, ? )
==> Parameters: 2342251622094285111(String),xxx, 2023-10-12 07:39:42.762(Timestamp), global_coding(String), 2023-10-12 07:39:42.762(Timestamp), global_coding(String)
<== Updates: 1
Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@2e62ead7]
Fetched SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@2e62ead7] from current transaction
==> Preparing: INSERT INTO xxx( xxx ) VALUES ( ?, ?, ?, ?, ?, ? )
==> Parameters: 2342251622094285112(String),xxx, 2023-10-12 07:39:42.762(Timestamp), global_coding(String), 2023-10-12 07:39:42.762(Timestamp), global_coding(String)
<== Updates: 1

我的打印:循环插入结束

Transaction synchronization committing SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@2e62ead7]
Transaction synchronization deregistering SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@2e62ead7]
Transaction synchronization closing SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@2e62ead7]
INFO 12-10-2023 07:40:10.436 main Committed transaction for test: [DefaultTestContext@5a8c93 testClass = T1, testInstance = com.ali.cloud.test.T1@3bed3315, testMethod = t1@T1, testException = java.lang.ArithmeticException: / by zero, mergedContextConfiguration = [MergedContextConfiguration@119b0892 testClass = T1, locations = ‘{}‘, classes = ‘{class com.ali.cloud.Application}‘, contextInitializerClasses = ‘[]‘, activeProfiles = ‘{}‘, propertySourceLocations = ‘{}‘, propertySourceProperties = ‘{com.baomidou.mybatisplus.test.autoconfigure.MybatisPlusTestContextBootstrapper=true}‘, contextCustomizers = set[[ImportsContextCustomizer@1a3e8e24 key = [org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration, org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration, org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration, org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration, org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration, org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration, org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration, com.baomidou.mybatisplus.autoconfigure.MybatisPlusLanguageDriverAutoConfiguration, com.baomidou.mybatisplus.autoconfigure.MybatisPlusAutoConfiguration, org.springframework.boot.test.autoconfigure.jdbc.TestDatabaseAutoConfiguration]], org.springframework.boot.test.context.filter.ExcludeFilterContextCustomizer@20d525, org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer@69453e37, org.springframework.boot.test.mock.mockito.MockitoContextCustomizer@0, org.springframework.boot.test.autoconfigure.OverrideAutoConfigurationContextCustomizerFactory$DisableAutoConfigurationContextCustomizer@4961f6af, org.springframework.boot.test.autoconfigure.filter.TypeExcludeFiltersContextCustomizer@351584c0, org.springframework.boot.test.autoconfigure.properties.PropertyMappingContextCustomizer@f1c9823f, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverContextCustomizerFactory$Customizer@4c309d4d], contextLoader = ‘org.springframework.boot.test.context.SpringBootContextLoader’, parent = [null]], attributes = map[[empty]]]
INFO 12-10-2023 07:40:10.455 SpringContextShutdownHook {dataSource-1} closing …
INFO 12-10-2023 07:40:10.463 SpringContextShutdownHook {dataSource-1} closed

_ _ |_ _ _|_. ___ _ | _
| | |\/|_)(_| | |_\ |_)||_|_\
/ |
3.3.0
INFO 13-10-2023 09:37:55.641 main Started T1 in 13.353 seconds (JVM running for 16.686)
我的打印 count: 2293
Creating a new SqlSession
SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@37348491] was not registered for synchronization because synchronization is not active
INFO 13-10-2023 09:37:56.937 main {dataSource-1} inited
JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@259b85d6] will not be managed by Spring
==> Preparing: SELECT xxx from xxx where xxx
==> Parameters: 5555b1e53dxxx0d09bcaaa0c6362ayyy(String), 1234b1e53dxxx0d09bcaaa0c6362axxx(String), 0(Integer)
<== Total: 0
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@37348491]
Creating a new SqlSession
SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@66bf40e5] was not registered for synchronization because synchronization is not active
JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@259b85d6] will not be managed by Spring
==> Preparing: INSERT INTO xxx( xxx ) VALUES ( ?, ?, ?, ?, ?, ? )
==> Parameters: 2342251622094285111(String),xxx, 2023-10-12 07:39:42.762(Timestamp), global_coding(String), 2023-10-12 07:39:42.762(Timestamp), global_coding(String)
<== Updates: 1
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@66bf40e5]
Creating a new SqlSession
SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@5a515e5d] was not registered for synchronization because synchronization is not active
JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@259b85d6] will not be managed by Spring
==> Preparing: SELECT xxx from xxx where xxx
==> Parameters: 5555b1e53dxxx0d09bcaaa0c6362ayyy(String), 1234b1e53dxxx0d09bcaaa0c6362axxx(String), 0(Integer)
<== Total: 0
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@5a515e5d]
Creating a new SqlSession
SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@32f32623] was not registered for synchronization because synchronization is not active
JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@259b85d6] will not be managed by Spring
==> Preparing: INSERT INTO xxx( xxx ) VALUES ( ?, ?, ?, ?, ?, ? )
==> Parameters: 2342251622094285111(String),xxx, 2023-10-12 07:39:42.762(Timestamp), global_coding(String), 2023-10-12 07:39:42.762(Timestamp), global_coding(String)
<== Updates: 1
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@32f32623]

我的打印:循环插入结束

INFO 13-10-2023 09:38:00.505 SpringContextShutdownHook {dataSource-1} closing …
INFO 13-10-2023 09:38:00.512 SpringContextShutdownHook {dataSource-1} closed

发表评论

表情:
评论列表 (有 0 条评论,109人围观)

还没有评论,来说两句吧...

相关阅读

    相关 spring手动事务控制

    在项目开发中需要用到手动事务进行控制。现说下遇到的问题以及解决方案: 如果程序需要使用嵌套事务,则需要在配置文件中添加一个配置属性,如下: <bean id="tr

    相关 spring手动事务控制

    在项目开发中需要用到手动事务进行控制。现说下遇到的问题以及解决方案: 如果程序需要使用嵌套事务,则需要在配置文件中添加一个配置属性,如下: <bean id="tr