说我有以下代码。请查阅。我在下面添加了我的问题:
Mybatis配置:
@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)
}
}
Dao层:
@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)
}
}
我假设在上面的示例中,如果有人调用了此方法
public addItems(List<Item> items){
for(Item item : items)
{
myDao.insertItem(item);
}
}
与调用相比,性能会降低
public addItemsBulk(List<String> items){
myDao.insertItems(items)
}
...由于 for循环的每次迭代,将发生以下情况:
- 会话模板使用会话工厂
- 会话工厂创建会话,打开连接。
- 会话工厂创建事务
- 会话工厂执行插入
- 会话工厂提交事务
- 会话工厂关闭会话
^因此,在此示例中,我假设:对于包含for循环的方法,将有多个会话,每个插入一个,每个会话有一个事务。
现在,如果在MyService类的顶部添加了 @Transactional 注释,会发生什么情况?
我假设两种情况下的性能相同,并且都是事件发生的顺序:
- 会话模板使用会话工厂
- 会话工厂创建会话,打开连接。
- 会话工厂创建事务
- 会话工厂执行所有插入语句
- 会话工厂提交事务
- 会话工厂关闭会话
^因此,在此示例中,我假设:对于包含for循环的方法,将有一个会话和一个事务。
我的推理是否正确?还是有缺陷?
答案 0 :(得分:1)
您的问题与@Transactional无关,但与Mybatis的Executor.BATCH的用法(等效于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();
}
}