Mybatis Spring - Управление транзакциями - PullRequest
0 голосов
/ 15 декабря 2018

Скажите, у меня есть следующий код.Пожалуйста ознакомтесь.Я добавил свои вопросы ниже:

Mybatis Config:

@Configuration
@ConfigurationProperties
public class MyMybatisConfiguration{

     @Bean
     public DataSource datasource(){
        //configure some db
     }

     @Bean
     public SqlSessionFactory sessionFactory(){
         SqlSessionFactoryBean ssfb = new SqlSessionFactoryBean();
         ssfb.setDataSource(dataSource())
         return ssfb;
     }

     @Bean
     public SqlSessionTemplate sessionTemplate(){
         return new SqlSessionTemplate(sessionFactory());
     }


 }

Уровень обслуживания:

@Service
public class MyService{

    public MyDao myDao;

    public MyService(MyDao myDao){
       this.myDao = myDao;
    }

    public addItems(List<Item> items){

       for(Item item : items)
       {
           myDao.insertItem(item);
       }  

    }

    public addItemsBulk(List<String> items){

        myDao.insertItems(items)

    }

}

Уровень Дао:

 @Repository
 public class MyDao {

      private SqlSessionTemplate tmp;

      @Autowired
      public MyDao(SqlSessionTemplate tmp){
          this.tmp = tmp;
      }


      public insertItem(Item item){
         sst.insert("insertItem", item)
      }

      public insertItems(List<Item> items){
         sst.insert("insertItems", items)
      }

    }

IЯ предполагаю, что в приведенном выше примере, если бы кто-то вызвал этот метод

public addItems(List<Item> items){

  for(Item item : items)
  {
       myDao.insertItem(item);
  }  

}

Он был бы менее производительным, чем вызов:

 public addItemsBulk(List<String> items){

     myDao.insertItems(items)

 }

... потому что для каждой итерациицикл for произойдет следующее:

  1. Шаблон сеанса использует фабрику сеансов
  2. Фабрика сеансов создает сеанс, открывая соединение.
  3. Фабрика сеансовсоздает транзакцию
  4. фабрика сессий выполняет вставку
  5. фабрика сессий фиксирует транзакцию
  6. фабрика сессий закрывает сессию

^ Так в этом примере Я предполагаю , что в случае метода, содержащего цикл for, будет несколько сессий, по одному на каждую вставку, с транзакцией на сессию.


Теперь что произойдет, еслиповерх класса MyService я добавил @ Transactional аннотация?

Я предполагаю, что производительность будет одинаковой и что порядок событий будет в обоих случаях:

  1. Используется шаблон сеансаФабрика сеанса
  2. Фабрика сеанса создает сеанс, открывая соединение.
  3. Фабрика сеанса создает транзакцию
  4. Фабрика сеанса выполняет ВСЕ операторы вставки
  5. Фабрика сеанса фиксирует транзакцию
  6. Session Factory закрывает сессию

^ Так что в этом примере Я предполагаю , что в случае метода, содержащего цикл for, будет один сеанси одна транзакция.

Правильно ли я рассуждаю или это неверно?

1 Ответ

0 голосов
/ 21 декабря 2018

Ваш вопрос относится не к @Transactional, а к использованию Executor.BATCH от Mybatis (что эквивалентно prepareStatement.executeBatch ())

Сравните разницу между вашим исходным решением и настройкой ниже:

Добавить ExecutorType.BATCH к SqlSessionTemplate:

@Configuration
@ConfigurationProperties
public class MyMybatisConfiguration{

     ...

     @Bean
     public SqlSessionTemplate sessionTemplate(){
         return new SqlSessionTemplate(sessionFactory(), ExecutorType.BATCH);
     }

 }

Объявить метод flushStatements:

@Repository
public class MyDao {
      ....
      public flush(){
         sst.flushStatements();
      }
}

Добавить сброс в addItems

public addItems(List<Item> items){

  for(Item item : items)
  {
       myDao.insertItem(item);
       myDao.flush();
  }  

}
...