Skip to content

This project is an extension of mybatis by using dynamic executor bound with current thread to solve 'Cannot change the ExecutorType when there is an existing transaction' for mybatis-spring project

Notifications You must be signed in to change notification settings

mycoco2014/mybatis-ex

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 
 
 
 
 
 
 

Repository files navigation

##Introduction

这个项目是基于mybatis、mybatis-spring的扩展,主要用来解决:
'Cannot change the ExecutorType when there is an existing transaction'异常的!
即:在同一个Session中不能动态切换ExecutorType的问题!

##Maven 构件已经被发布到Maven中央库中:

版本1.0.0 支持mybatis 3.2|3.3版本
版本1.0.1 支持mybatis 3.4版本	

<dependency>
	<groupId>com.github.penggle</groupId>
	<artifactId>mybatis-ex</artifactId>
	<version>1.0.1</version>
</dependency>

##Example

1、Simple usage as follows (No Spring integration) :

/**
 * returned DefaultExSqlSessionFactory as default
 */
public SqlSessionFactory getSqlSessionFactory() {
	InputStream inputStream = Resources.getResourceAsStream("mybatis/mybatis-config.xml");
	return new ExSqlSessionFactoryBuilder().build(inputStream);
}

public void testNormalInsertAndBatchInsert() throws Exception {
	SqlSession sqlSession = null;
	try {
		sqlSession = getSqlSessionFactory().openSession(ExecutorType.SIMPLE, false);
		//1、No-batch execution mode for insert
		for(int i = 1; i <= 5; i++){
			Product product = new Product(...);
			int affectedRow = sqlSession.insert(getMapperKey(Product.class, "insertProduct"), product);
			System.out.println(">>> inserted rows " + affectedRow);
		}
		
		//2、batch execution mode for insert by using BatchTemplate
		BatchTemplate batchTemplate = new BatchTemplate(sqlSession);
		List<Integer> batchResultList = batchTemplate.execute(new SqlSessionCallback<List<Integer>>(){
			public List<Integer> doInSqlSession(SqlSession sqlSession) {
				List<Integer> list = new ArrayList<Integer>();
				for(int i = 6; i <= 10; i++){
					Product product = new Product(...);
					sqlSession.insert(getMapperKey(Product.class, "insertProduct"), product);
				}
				BatchResultUtils.extractBatchResult(list, sqlSession.flushStatements());
				return list;
			}
		});
		System.out.println(">>> batch inserted rows " + batchResultList.size());
		sqlSession.commit();
	} catch(Exception e) {
		sqlSession.rollback();
		e.printStackTrace();
	} finally {
		if(sqlSession != null){
			sqlSession.close();
		}
	}
}

public void testInsertOrder() throws Exception {
	MainOrder mainOrder = new MainOrder(...);
	List<ChildOrder> childOrderList = new ArrayList<ChildOrder>();
	for(int i = 1; i <= 5; i++){
		ChildOrder childOrder = new ChildOrder(...);
		childOrderList.add(childOrder);
	}
	ExSqlSession sqlSession = null;
	try {
		sqlSession = (ExSqlSession) getSqlSessionFactory().openSession(ExecutorType.SIMPLE, false);
		//1、No-batch execution mode for insert
		int affectedRow = sqlSession.insert(getMapperKey(MainOrder.class, "insertMainOrder"), mainOrder);
		System.out.println(">>> inserted rows " + affectedRow);
		
		//2、batch execution mode for insert by using extension method
		int[] affectedRows = sqlSession.batchInsert(getMapperKey(ChildOrder.class, "insertChildOrder"), childOrderList);
		System.out.println(">>> inserted rows " + affectedRows.length);
		sqlSession.commit();
	} catch (Exception e) {
		sqlSession.rollback();
		e.printStackTrace();
	} finally {
		if(sqlSession != null){
			sqlSession.close();
		}
	}
}

2、Simple usage as follows (With Spring integration) :

2.1、Spring applicationContext.xml :

<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close">
	...
</bean>

<bean id="jdbcTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource"/>
</bean>

<tx:annotation-driven transaction-manager="jdbcTransactionManager" proxy-target-class="true"/>

<bean id="sqlSessionFactory" class="com.penglecode.mybatis.ex.spring.SimpleExSqlSessionFactoryBean">
    <property name="configLocation" value="classpath:mybatis/spring/mybatis-config.xml"/>
    <property name="dataSource" ref="dataSource"/>
</bean>

<bean id="sqlSessionTemplate" class="com.penglecode.mybatis.ex.spring.ExSqlSessionTemplate">
	<constructor-arg index="0" ref="sqlSessionFactory"/>
	<constructor-arg index="1" value="SIMPLE"/>
</bean>

2.1、Java code: 

/**
 * sqlSessionTemplate actual type is ExSqlSessionTemplate
 */
@Resource(name="sqlSessionTemplate")
private ExSqlSession sqlSessionTemplate;

@Test
@Transactional(propagation=Propagation.REQUIRED,rollbackFor=Exception.class)
public void testInsertOrder() throws Exception {
	MainOrder mainOrder = new MainOrder(...);
	List<ChildOrder> childOrderList = new ArrayList<ChildOrder>();
	for(int i = 1; i <= 5; i++){
		ChildOrder childOrder = new ChildOrder(...);
		childOrderList.add(childOrder);
	}
	//1、No-batch execution mode for insert
	int affectedRow = sqlSessionTemplate.insert(getMapperKey(MainOrder.class, "insertMainOrder"), mainOrder);
	System.out.println(">>> inserted rows " + affectedRow);
	//2、batch execution mode for insert by using extension method
	int[] affectedRows = sqlSessionTemplate.batchInsert(getMapperKey(ChildOrder.class, "insertChildOrder"), childOrderList);
	System.out.println(">>> inserted rows " + affectedRows.length);
}

About

This project is an extension of mybatis by using dynamic executor bound with current thread to solve 'Cannot change the ExecutorType when there is an existing transaction' for mybatis-spring project

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages