3、在src文件夹下面加入一个transactions.properties文件
# SAMPLE PROPERTIES FILE FOR THE TRANSACTION SERVICE
# THIS FILE ILLUSTRATES THE DIFFERENT SETTINGS FOR THE TRANSACTION MANAGER
# UNCOMMENT THE ASSIGNMENTS TO OVERRIDE DEFAULT VALUES;
# Required: factory implementation class of the transaction core.
# NOTE: there is no default for this, so it MUST be specified!
#
com.atomikos.icatch.service=com.atomikos.icatch.standalone.UserTransactionServiceFactory
# Set base name of file where messages are output
# (also known as the 'console file')。
#
# com.atomikos.icatch.console_file_name = tm.out
# Size limit (in bytes) for the console file;
# negative means unlimited.
#
# com.atomikos.icatch.console_file_limit=-1
# For size-limited console files, this option
# specifies a number of rotating files to
# maintain.
#
# com.atomikos.icatch.console_file_count=1
# Set the number of log writes between checkpoints
#
# com.atomikos.icatch.checkpoint_interval=500
# Set output directory where console file and other files are to be put
# make sure this directory exists!
#
# com.atomikos.icatch.output_dir = ./
# Set directory of log files; make sure this directory exists!
#
# com.atomikos.icatch.log_base_dir = ./
# Set base name of log file
# this name will be used as the first part of
# the system-generated log file name
#
# com.atomikos.icatch.log_base_name = tmlog
# Set the max number of active local transactions
# or -1 for unlimited.
#
# com.atomikos.icatch.max_actives = 50
# Set the default timeout (in milliseconds) for local transactions
#
# com.atomikos.icatch.default_jta_timeout = 10000
# Set the max timeout (in milliseconds) for local transactions
#
# com.atomikos.icatch.max_timeout = 300000
# The globally unique name of this transaction manager process
# override this value with a globally unique name
#
# com.atomikos.icatch.tm_unique_name = tm
# Do we want to use parallel subtransactions? JTA's default
# is NO for J2EE compatibility
#
# com.atomikos.icatch.serial_jta_transactions=true
# If you want to do explicit resource registration then
# you need to set this value to false.
#
# com.atomikos.icatch.automatic_resource_registration=true
# Set this to WARN, INFO or DEBUG to control the granularity
# of output to the console file.
#
# com.atomikos.icatch.console_log_level=WARN
# Do you want transaction logging to be enabled or not?
# If set to false, then no logging overhead will be done
# at the risk of losing data after restart or crash.
#
# com.atomikos.icatch.enable_logging=true
# Should two-phase commit be done in (multi-)threaded mode or not?
# Set this to false if you want commits to be ordered according
# to the order in which resources are added to the transaction.
#
# NOTE: threads are reused on JDK 1.5 or higher.
# For JDK 1.4, thread reuse is enabled as soon as the
# concurrent backport is in the classpath - see
# http://mirrors.ibiblio.org/pub/mirrors/maven2/backport-util-concurrent/backport-util-concurrent/
#
# com.atomikos.icatch.threaded_2pc=false
# Should shutdown of the VM trigger shutdown of the transaction core too?
#
# com.atomikos.icatch.force_shutdown_on_vm_exit=false
4、注入HibernateTemplate模板
a、为tms库注入HibernateTemplate模板
package com.test.dao.impl;
import java.io.Serializable;
import java.util.List;
import org.hibernate.criterion.DetachedCriteria;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import org.springframework.stereotype.Repository;
import com.test.dao.BaseDao;
@Repository("tmsDao")
public class TmsBaseDaoImpl extends HibernateDaoSupport implements BaseDao{
protected HibernateTemplate tmsHibernateTemplate;
@Autowired
public void setTmsHibernateTemplate(HibernateTemplate tmsHibernateTemplate) {
this.tmsHibernateTemplate = tmsHibernateTemplate;
super.setHibernateTemplate(tmsHibernateTemplate);
}
@SuppressWarnings("rawtypes")
@Override
public List findAll(String hql) throws Exception {
return tmsHibernateTemplate.find(hql);
}
@SuppressWarnings("rawtypes")
@Override
public List query(String hql,Object value) throws Exception {
return tmsHibernateTemplate.find(hql, value);
}
@Override
public Serializable save(T entity) throws Exception {
Serializable s = tmsHibernateTemplate.save(entity);
return s;
}
@SuppressWarnings("unchecked")
@Override
public List find(DetachedCriteria detachedCriteria) throws Exception {
return tmsHibernateTemplate.findByCriteria(detachedCriteria);
}
}
b、为his库注入HibernateTemplate模板
package com.test.dao.impl;
import java.io.Serializable;
import java.util.List;
import org.hibernate.criterion.DetachedCriteria;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import org.springframework.stereotype.Repository;
import com.test.dao.BaseDao;
@Repository("hisDao")
public class HisBaseDaoImpl extends HibernateDaoSupport implements BaseDao{
protected HibernateTemplate hisHibernateTemplate;
@Autowired
public void setHisHibernateTemplate(HibernateTemplate hisHibernateTemplate) {
this.hisHibernateTemplate = hisHibernateTemplate;
super.setHibernateTemplate(hisHibernateTemplate);
}
@SuppressWarnings("rawtypes")
@Override
public List findAll(String hql) throws Exception {
return hisHibernateTemplate.find(hql);
}
@SuppressWarnings("rawtypes")
@Override
public List query(String hql,Object value) throws Exception {
return hisHibernateTemplate.find(hql, value);
}
@Override
public Serializable save(T entity) throws Exception {
Serializable s = hisHibernateTemplate.save(entity);
return s;
}
@SuppressWarnings("unchecked")
@Override
public List find(DetachedCriteria detachedCriteria) throws Exception {
return hisHibernateTemplate.findByCriteria(detachedCriteria);
}
}
5、编写业务逻辑代码
package com.test.service.impl;
import java.util.List;
import javax.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import com.test.dao.BaseDao;
import com.test.entity.HisTest;
import com.test.entity.TmsTest;
import com.test.service.BaseService;
@Service
@Transactional(propagation=Propagation.REQUIRED)
public class BaseServiceImpl implements BaseService{
@Resource
private BaseDao tmsDao;
@Resource
private BaseDao hisDao;
@SuppressWarnings("rawtypes")
@Override
public List findTms() throws Exception {
/*DataSourceContextHolder.setDataSourceType(DataSourceConst.TMS_STRING);
String hql = "from MedicalCard";
return tmsDao.findAll(hql);*/
String hql = "FROM TmsTest";
return tmsDao.findAll(hql);
}
@SuppressWarnings("rawtypes")
public List findHis() throws Exception{
/*DataSourceContextHolder.setDataSourceType(DataSourceConst.HIS_STRING);
String hql = "from Patient where idNo = ?";
return hisDao.query(hql, idNo);*/
String hql = "FROM HisTest";
return hisDao.findAll(hql);
}
@Override
public void save(TmsTest tms, HisTest his) throws Exception {
tmsDao.save(tms);
hisDao.save(his);
}
}
测试方法
package com.test.junit;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.test.entity.HisTest;
import com.test.entity.TmsTest;
import com.test.service.BaseService;
public class TestService {
private BaseService service;
TmsTest tmsTest;
HisTest hisTest;
@Before
public void init(){
ApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"applicationContext.xml"});
BeanFactory factory = (BeanFactory) context;
service = factory.getBean("BaseService",BaseService.class);
tmsTest = new TmsTest();
tmsTest.setName("张三");
hisTest = new HisTest();
hisTest.setName("李四李四李四李四李四李四李四李四李四李四");
}
@Test
public void testDataSource() {
try {
@SuppressWarnings("unchecked")
List tmsList = service.findTms();
System.out.println("tms============" + tmsList.get(0)。getName());
} catch (Exception e) {
e.printStackTrace();
}
try {
@SuppressWarnings("unchecked")
List hisList = service.findHis();
System.out.println("his=================" + hisList.get(0)。getName());
} catch (Exception e) {
e.printStackTrace();
}
try {
service.save(tmsTest, hisTest);
} catch (Exception e) {
System.out.println("保存操作失败,事务整体回滚。");
}
}
}
在执行save()方法时会报异常,hisTest的name字段过长;
如果事务生效,save()方法会回滚掉,两张表都不会有save操作,保持事务的原子性;
如果事务不起作用,那么tmsTest插入操作会执行成功,往数据库添加一条记录;hisTest插入操作抛出异常终止向下执行;
Atomikos的集成到此就结束了。
注意
mysql的驱动需要5.1.10版本以上,低版本会出现如下错误:
java.lang.IllegalArgumentException: null source