比较典型的spring的数据库事务配置
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd" default-lazy-init="true"> <!-- 加载 db.properties文件--> <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="locations"> <list> <value>classpath*:db.properties</value> </list> </property> </bean> <!-- SessionFactory --> <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"> <property name="hibernateProperties"> <props> <prop key="hibernate.dialect">${dialect}</prop> <prop key="hibernate.connection.driver_class">${driverClassName}</prop> <prop key="hibernate.connection.url">${dataSourceUrl}</prop> <prop key="hibernate.connection.username">${username}</prop> <prop key="hibernate.connection.password">${password}</prop> <prop key="hibernate.show_sql">${show_sql}</prop> <prop key="hibernate.format_sql">true</prop> <prop key="hibernate.jdbc.fetch_size">25</prop> <prop key="hibernate.jdbc.batch_size">50</prop> <prop key="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</prop> <prop key="current_session_context_class">${current_session_context_class}</prop> <prop key="hibernate.cache.use_query_cache">true</prop> <prop key="hibernate.connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</prop> <prop key="hibernate.c3p0.max_size">20</prop> <prop key="hibernate.c3p0.min_size">5</prop> <prop key="hibernate.c3p0.timeout">28800</prop> <prop key="hibernate.c3p0.max_statements">100</prop> <prop key="hibernate.c3p0.idle_test_period">120</prop> <prop key="hibernate.c3p0.acquire_increment">2</prop> </props> </property> <property name="mappingResources"> <list> <value>com/model/User.hbm.xml</value> </list> </property> </bean> <!-- spring管理hibernate的数据库session的bean --> <bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate"> <property name="sessionFactory" ref="sessionFactory"></property> </bean> <!-- 配置事务管理器 --> <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> <property name="sessionFactory"> <ref local="sessionFactory"/> </property> </bean> <!-- 配置事务特性 ,配置add、delete和update开始的方法,事务传播特性为required--> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes> <tx:method name="insert*" propagation="REQUIRED"/> <tx:method name="delete*" propagation="REQUIRED"/> <tx:method name="update*" propagation="REQUIRED"/> <tx:method name="login*" propagation="REQUIRED"/> <tx:method name="regist*" propagation="REQUIRED"/> <tx:method name="*" read-only="true"/> </tx:attributes> </tx:advice> <!-- 配置那些类的方法进行事务管理,当前cn.com.jobedu.oa.service包中的子包、类中所有方法需要,还需要参考tx:advice的设置--> <aop:config> <aop:pointcut id="allManagerMethod" expression="execution (* com..*.service.*.*(..))"/> <aop:advisor advice-ref="txAdvice" pointcut-ref="allManagerMethod"/> </aop:config> </beans>
db.properties
datasourceType=oracle
dialect=org.hibernate.dialect.Oracle10gDialect
driverClassName=oracle.jdbc.driver.OracleDriver
dataSourceUrl=jdbc:oracle:thin:@127.0.0.1:1521:orcl
username=ssh
password=ssh
show_sql=true
current_session_context_class=thread
expression配置说明:
例如:
expression="execution (public * com.test..*.service.*.*(..))"
第一个public表示只对public的方法有效
第二个*号表示任意返回值
第三个com.test..*表示所有com.test下的所有不限制层级的子包
第四个service.*.*(..)表示service包下的任意类的任意方法任意入参类型
.*:只是一个层级
..:是取所有层级
Propagation的可配置项:
PROPAGATION_REQUIRED:支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。
PROPAGATION_SUPPORTS:支持当前事务,如果当前没有事务,就以非事务方式执行。
PROPAGATION_MANDATORY:支持当前事务,如果当前没有事务,就抛出异常。
PROPAGATION_REQUIRES_NEW:新建事务,如果当前存在事务,把当前事务挂起。
PROPAGATION_NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
PROPAGATION_NEVER:以非事务方式执行,如果当前存在事务,则抛出异常。
PROPAGATION_NESTED:支持当前事务,如果当前事务存在,则执行一个嵌套事务,如果当前没有事务,就新建一个事务
在配置spring的jdbcTemplte事务时发现本来是只读事务的确也开启了事务,经过测试后修改
<tx:method name="*" read-only="true"/>
修改为---》
<tx:method name="*" propagation="NOT_SUPPORTED" read-only="true" />
修改后的效果是只读事务不再有回滚操作,SQL的写操作自动提交,写操作不会报错。