spring事务有两种:编程式和声明式。
一、编程式:
DataSource ds = SpringUtil.getBean("dataSource");
long startTs = System.currentTimeMillis();
PlatformTransactionManager ptm = new DataSourceTransactionManager(ds);
DefaultTransactionDefinition def = new DefaultTransactionDefinition();
TransactionStatus status = ptm.getTransaction(def);
try {
// 业务代码
Document doc;
// 当前系统时间
String Ddate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
.format(new Date());
// inxml格式的转换
if (inXml == null) {
}
String inXml1 = inXml.replaceAll("<", "<");
String inXml2 = inXml1.replaceAll(""", "\"");
String inXml3 = inXml2.replaceAll(">", ">");
String inXml4 = (String) inXml3.replace(
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>", "");
try {
doc = DocumentHelper.parseText(inXml4);
// 保存inxml
String xmlStr = doc.asXML();
Element sendDate = (Element) doc
.selectSingleNode("/Msg/Head/Date-Time");
InInXml inInXml = new InInXml();
inInXml.setXmlInfo(xmlStr);
if ("".equals(sendDate.getText())) {
}
inInXml.setSendDateTime(Timestamp.valueOf(sendDate.getText()));
inInXml.setReceiveDateTime(Timestamp.valueOf(Ddate));
inInXml.setDataState("1");
inInXml.setXmlId("");
baseDao.saveObject(inInXml);
// 解析
List headList = doc.getRootElement().selectNodes("/Msg/Head/*");
Map headMap = new HashMap();
for (Iterator it = headList.iterator(); it.hasNext();) {
Element element = (Element) it.next();
headMap.put(element.getName(), element.getText());
}
List tabkleNode = doc.selectNodes("/Msg/DATA/*");
String tableName = ((Node) tabkleNode.get(0)).getText();
if (tableName.equals("IrmOrgUnit")) {
String action = ((Node) tabkleNode.get(0)).getText();
IrmOrgUnit irmOrgUnit = new IrmOrgUnit();
HashMap map = new HashMap();
irmOrgUnit.setOrgUnitId("");
for (int i = 1; i < tabkleNode.size(); i++) {
Node e = (Node) tabkleNode.get(i);
if ("LIFNR".equals(e.getName())) {
irmOrgUnit.setOrgUnitCd(e.getText());
} else if ("NAME1_GP".equals(e.getName())) {
irmOrgUnit.setOrgUnitName(e.getText());
} else if ("BUKRS".equals(e.getName())) {
} else if ("SORTL".equals(e.getName())) {
} else if ("KTOKK".equals(e.getName())) {
} else if ("TXT30".equals(e.getName())) {
} else if ("STRAS".equals(e.getName())) {
irmOrgUnit.setUnitAddr(e.getText());
} else if ("ORT01".equals(e.getName())) {
} else if ("TELF1".equals(e.getName())) {
irmOrgUnit.setContactTel(e.getText());
} else if ("NAME1".equals(e.getName())) {
irmOrgUnit.setContact(e.getText());
} else if ("EKORG".equals(e.getName())) {
} else if ("WAERS".equals(e.getName())) {
} else if ("REGIO".equals(e.getName())) {
irmOrgUnit.setAreaCd(e.getText());
} else if ("BEZEI".equals(e.getName())) {
} else if ("lo".equals(e.getName())) {
irmOrgUnit.setDataState("1"); // 空为1,x为0
} else if ("telfx".equals(e.getName())) {
irmOrgUnit.setUnitFax(e.getText());
} else if ("pstlz".equals(e.getName())) {
irmOrgUnit.setUnitPostalcode(e.getText());
}
}
// 校验保存
baseDao.saveObject(irmOrgUnit);
InIdContrast inIdContrast = new InIdContrast();
inIdContrast.setXmlId(inInXml.getXmlId());
inIdContrast.setTlirmId(irmOrgUnit.getOrgUnitId());
inIdContrast.setBillType(tableName);
inIdContrast.setModifyType("1");
inIdContrast.setModifyTime(Timestamp.valueOf(Ddate));
inIdContrast.setDataState("1");
// sap供应商编码保存在inIdContrast的sapId字段
inIdContrast.setSapId(irmOrgUnit.getOrgUnitCd());
baseDao.saveObject(inIdContrast);
List dateTime = returnXml.selectNodes("//Date-Time");
for (Iterator iterator = dateTime.iterator(); iterator
.hasNext();) {
Element data = (Element) iterator.next();
data.addText(Ddate);
}
returnXml.selectSingleNode("/MSG/DATA/Return-Result").setText("true");
returnXml.selectSingleNode("/MSG/DATA/Reason").setText("true");
InReturnXml inReturnXml = new InReturnXml();
inReturnXml.setXmlId(inInXml.getXmlId());
inReturnXml.setReturnInfo(returnXml.asXML());
baseDao.saveObject(inReturnXml);
}
} catch (DocumentException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
ptm.commit(status);
} catch (Throwable e) {
ptm.rollback(status);
//返回错误信息
returnXml.selectSingleNode("/MSG/DATA/Return-Result").setText("false");
returnXml.selectSingleNode("/MSG/DATA/Reason").setText(e.getMessage());
throw new RuntimeException("执行出错!", e);
} finally {
log.debug("执行时间:" + (System.currentTimeMillis() - startTs));
}
String eee = returnXml.getRootElement().asXML();
return eee;
}
二、声明式:
Spring也提供声明式事务管理。这是通过AOP实现的。大多数Spring用户选择声明式事务管理,这是最少影响应用代码的选择,因而这是和非侵入性的轻量级容器的观念是一致的。
1)通常通过TransactionProxyFactoryBean设置Spring事务代理。需要一个目标对象包装在事务代理中。这个目标对象一般是一个普通Javabean。当我们定义TransactionProxyFactoryBean时,必须提供一个相关的 PlatformTransactionManager的引用和事务属性。事务属性含有事务定义。例如:
- <bean id="transactionService"class="org.springframework. transaction.interceptor.TransactionProxyFactoryBean">
- <property name="transactionManager">
- <ref local="transactionManager"/>
- property>
- <property name="target">
- <ref local="transactionServiceControl"/>
- property>
- <property name="transactionAttributes">
- <props>
- <prop key=”insert*”>PROPAGATION_REQUIRED,-MyCheckedExceptionprop>
- <prop key=”update*”>PROPAGATION_REQUIREDprop>
- <prop key=”*”>PROPAGATION_REQUIRED,readOnlyprop>
- props>
- property>
- bean>
事务代理会实现目标对象的接口:这里是属性名是target的引用。id是transactionServiceControl。(使用CGLIB也可以实现具体类的代理。只要设置proxyTargetClass属性为true即可。如果目标对象没有实现任何接口,这将自动设置该属性为true。通常,我们希望面向接口编程。)使用proxyInterfaces属性来限定事务代理来代理指定接口也是可以。 也可以通过从org.springframework.aop.framework.ProxyConfig继承或所有AOP代理工厂共享的属性来定制 TransactionProxyFactoryBean行为。
然后,说说属性名是transactionAttributes意义:
这里的transactionAttributes属性是定义在 org.springframework.transaction.interceptor.NameMathTransactionAttributeSource 中的属性格式设置。这个包括通配符的方法名称映射是很直观的,如”insert*”。注意insert*的映射的值包括回滚规则。”- MyCheckException”指定如果方法抛出MyCheckException或它的子类,事务会自动回滚。可以用逗号分隔多个回滚规则。“-” 前缀强制回滚,“+”前缀指定提交(这允许即使抛出unchecked异常时也可以提交事务)。“PROPAGATION_REQUIRED”指定事务传播范围。
TransactionProxyFactoryBean允许你通过“preInterceptors”和 “postInterceptors”属性设置前或后的拦截操作。可以设置任意数量的前和后通过,它们的类型可以是Advistor(切入点),MethodInterceptor或被当前Spring配置支持的通知类型。例如:ThrowAdvice,AfterReturningAdvice或BeforeAdvice。这些通知必须支持实例共享模式。如果你需要高级 AOP特性操作事务,通过org.springframework.aop.framework.ProxyFactoryBean,而不是 TransactionProxyFactory实用代理创建者。
2)另一种声明方式:BeanNameAutoProxyCreator
使用TransactionProxyFactoryBean当事务代理包装对象,你可以完全控制代理。如果需要用一致方式包装大量bean。使用一个 BeanFactoryPostProcessor的一个实现,BeanNameAutoProxyCreator,可以提供另外一种方法。(Spring中,一旦ApplicationContext读完它的初始化信息,它将初始化所有实现BeanPostProcessor接口的 bean,并且让它们后处理ApplicationContext中所有其他的bean。所以使用这种机制,正确配置的 BeanNameAutoProxyCreator可以用来后处理所有ApplicationContext中所有其他的bean),并且把它们用事务代理包装起来。真正生成的事务代理和使用TransactionProxyFactoryBean生成的基本一致。