涉及内容:
1、spring整合hibernate
2、声明式事务和编程式事务嵌套
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
">
<!-- Hibernate4 -->
<!-- 加载资源文件 其中包含变量信息,必须在Spring配置文件的最前面加载,即第一个加载 -->
<context:property-placeholder location="classpath:hibernate-sql.properties" />
<!-- ①datasource -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="oracle.jdbc.driver.OracleDriver">
</property>
<property name="jdbcUrl" value="jdbc:oracle:thin:@x.x.x.x:1522:orcl">
</property>
<property name="user" value="user"></property>
<property name="password" value="pwd"></property>
<property name="minPoolSize">
<value>10</value>
</property>
<property name="maxPoolSize">
<value>500</value>
</property>
<property name="maxIdleTime">
<value>1800</value>
</property>
<property name="acquireIncrement">
<value>2</value>
</property>
<property name="maxStatements">
<value>0</value>
</property>
<property name="initialPoolSize">
<value>2</value>
</property>
<property name="idleConnectionTestPeriod">
<value>1800</value>
</property>
<property name="acquireRetryAttempts">
<value>30</value>
</property>
<property name="breakAfterAcquireFailure">
<value>true</value>
</property>
<property name="testConnectionOnCheckout">
<value>false</value>
</property>
</bean>
<!--②sessionFactory-->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan">
<list>
<!-- 可以加多个包 -->
<value>com.act.erp.entity</value>
<value>com.act.demo.entity</value>
<value>com.act.common.entity</value>
<value>com.act.common.message</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<!-- <prop key="hibernate.connection.driverClass">${hibernate.connection.driverClass}</prop>
<prop key="hibernate.connection.url">${hibernate.connection.url}</prop> -->
<prop key="hibernate.dialect">com.act.common.dao.Oracle12cDialect</prop>
<!-- <prop key="hibernate.connection.username">${hibernate.connection.username}</prop>
<prop key="hibernate.connection.password">${hibernate.connection.password}</prop> -->
<prop key="hibernate.show_sql">true</prop>
<!-- <prop key="hibernate.current_session_context_class">thread</prop> -->
<prop key="hibernate.connection.autocommit">false</prop>
<prop key="hibernate.format_sql">true</prop>
</props>
</property>
</bean>
<!-- ③配置Hibernate事务管理器 -->
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<!-- JTA事务管理器 -->
<!-- <bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager">
<property name="userTransaction" ref="jotm" /> </bean> -->
<bean id="hibernateTemplate" class="org.springframework.orm.hibernate4.HibernateTemplate">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource" />
</bean>
<!--④txTemplate 用于编程式事务-->
<bean id="txTemplate"
class="org.springframework.transaction.support.TransactionTemplate">
<property name="transactionManager">
<ref bean="transactionManager"/>
</property>
</bean>
<!-- 配置事务异常封装 -->
<bean id="persistenceExceptionTranslationPostProcessor"
class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />
</beans>
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">
<context:component-scan base-package="com.act.erp,com.act.demo,com.act.common">
<context:exclude-filter type="regex"
expression=".*Config" />
</context:component-scan>
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="*" propagation="REQUIRED" />
</tx:attributes>
</tx:advice>
<!-- 服务层事务拦截 -->
<aop:config>
<aop:pointcut expression="execution(* com.act.*.service..*.*(..))"
id="p" />
<aop:pointcut
expression="execution(* com.act.common.workflow.WorkFlowEngine.*(..))"
id="pwf" />
<aop:advisor advice-ref="txAdvice" pointcut-ref="p" />
<aop:advisor advice-ref="txAdvice" pointcut-ref="pwf" />
</aop:config>
二、声明式事务和编程式事务嵌套
使用场景:
aspect和自定义annotation 处理日志、检测等特殊情况时,且不与service共用事务时(独立事务)
使用 transactionTemplate XXXTemplate 设计模式:模板
关键点:
①设置编程时事务的传播特性
txTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
②txTemplate.execute参数有2种,借助(TransactionCallback)执行事务管理,既带有返回值:
借助(TransactionCallbackWithoutResult)执行事务管理,既无返回值:
③将业务代码包裹在try catch中,发生异常后,可rollback
package com.act.util.mvc.config.aop;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.DefaultTransactionDefinition;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;
import com.act.common.dao.IdGen;
import com.act.common.message.MessageService;
import com.act.common.message.MessageType;
import com.act.common.support.SysTime;
import com.act.common.workflow.SubmitActivitiEvent;
@Aspect
public class TransactionCheckAspect{
@Autowired
private MessageService messageService;
@Autowired
private JdbcTemplate jdbctemplate;
@Autowired
private TransactionTemplate txTemplate;
protected Logger logger = LoggerFactory.getLogger(getClass());
@Pointcut(value="@annotation(com.act.util.TransactionCheck)")
public void TransactionAspect() {
}
/**
* 异常通知
*
* @param joinPoint
* @param e
*/
@AfterThrowing(pointcut="TransactionAspect()",throwing="exception")
public void afterThrowing(JoinPoint joinPoint,Exception exception) {
String className= joinPoint.getTarget().getClass().getName();
String methodName =joinPoint.getSignature().getName();
Object[] args =joinPoint.getArgs();
SubmitActivitiEvent arg= (SubmitActivitiEvent) args[0];
if(arg==null){
logger.error("aop annotation decorate error!!");
return;
}
String bizId =arg.getBusinessKey();
String bizType =arg.getProcessDefinitionKey();
String task =arg.getPreTaskDefKey();
String exceptionName=exception.getClass().getName();
String msg="流程:%s的环节:%s办理时,发生异常:%s.业务Id:%s,定位class:%s,method:%s";
String msgFormat=String.format(msg,bizType,task,exceptionName,bizId,className,methodName);
txTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
txTemplate.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus status) {
try{
// TODO Auto-generated method stub
//业务代码--与service层事务不相关的 日志点等
}
catch(Exception e){
status.setRollbackOnly();
}
}
});
logger.error(msgFormat);
}
}