<!-- 数据源 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="driverClass" value="${jdbc.driver}" />
<property name="jdbcUrl" value="${jdbc.url}" />
<property name="user" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<property name="initialPoolSize" value="${connection_pools.initial_pool_size}" />
<property name="minPoolSize" value="${connection_pools.min_pool_size}" />
<property name="maxPoolSize" value="${connection_pools.max_pool_size}" />
<property name="maxIdleTime" value="${connection_pools.max_idle_time}" />
<property name="acquireIncrement" value="${connection_pools.acquire_increment}" />
<property name="checkoutTimeout" value="${connection_pools.checkout_timeout}" />
</bean>
<!-- 基于JPA的HibernateEntityManagerFactory ? -->
<!-- 还是说Hibernate本身就是JPA的实现,所以谈不上基于?没太弄明白 -->
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="persistenceXmlLocation" value="classpath*:/persistence.xml" />
<property name="persistenceUnitName" value="persistenceUnit" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="false" />
<property name="generateDdl" value="true" />
</bean>
</property>
<property name="jpaProperties">
<props>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.ejb.naming_strategy">org.hibernate.cfg.ImprovedNamingStrategy</prop>
<prop key="hibernate.cache.use_second_level_cache">${hibernate.cache.use_second_level_cache}</prop>
<prop key="hibernate.cache.region.factory_class">${hibernate.cache.region.factory_class}</prop>
<prop key="hibernate.cache.use_query_cache">${hibernate.cache.use_query_cache}</prop>
<prop key="hibernate.jdbc.fetch_size">${hibernate.jdbc.fetch_size}</prop>
<prop key="hibernate.jdbc.batch_size">${hibernate.jdbc.batch_size}</prop>
<prop key="hibernate.connection.isolation">2</prop>
<prop key="javax.persistence.validation.mode">none</prop>
<prop key="hibernate.search.default.directory_provider">org.hibernate.search.store.FSDirectoryProvider</prop>
<prop key="hibernate.search.default.indexBase">${java.io.tmpdir}/${system.project_name}/index</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">true</prop>
<prop key="hibernate.use_sql_comments">false</prop>
</props>
</property>
</bean>
<!-- 配置TransactionManager,注意,这里要用JpaTransactionManager -->
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<!-- 最后就是配置事务的注解 -->
<tx:annotation-driven transaction-manager="transactionManager" />
已上是applicationContentxml里要配置的,接下来就是在程序里加上注解了
//通过注解给buildIndex方法配上事务,readOnly= true为只读事务
@Transactional(readOnly = true)
public int buildIndex() {
Template template = templateService.get("index");
return build(template.getTemplatePath(), template.getStaticPath());
}
以下为其他使用方法
//方法中抛出指定异常时进行回滚
@Transactional(rollbackFor=RuntimeException.class)
public void func(){
//...
}
//方法中抛出指定多个异常中的某一个时进行回滚
@Transactional(rollbackFor={RuntimeException.class, Exception.class})
public void func(){
//...
}
//方法中抛出指定异常时进行回滚,根据ClassName捕捉
@Transactional(rollbackForClassName="RuntimeException")
public void func(){
//...
}
//方法中抛出指定多个异常中的一个时进行回滚,根据ClassName捕捉
@Transactional(rollbackForClassName={"RuntimeException","Exception"})
public void func(){
//...
}
//指定方法中抛出的哪个异常不回滚
@Transactional(noRollbackFor=RuntimeException.class)
public void func(){
//...
}
//指定方法中抛出的哪些异常不回滚
@Transactional(noRollbackFor={RuntimeException.class, Exception.class})
public void func(){
//...
}
//指定方法中抛出的哪个异常不回滚,根据className捕捉
@Transactional(noRollbackForClassName="RuntimeException")
public void func(){
//...
}
//指定方法中抛出的哪些异常不回滚,根据className捕捉
@Transactional(noRollbackForClassName={"RuntimeException","Exception"})
public void func(){
//...
}
//指定事务的传播属性
//Propagation.REQUIRED--支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。
//Propagation.SUPPORTS--支持当前事务,如果当前没有事务,就以非事务方式执行。
//Propagation.MANDATORY--支持当前事务,如果当前没有事务,就抛出异常。
//Propagation.REQUIRES_NEW--新建事务,如果当前存在事务,把当前事务挂起。
//Propagation.NOT_SUPPORTED--以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
//Propagation.NEVER--以非事务方式执行,如果当前存在事务,则抛出异常。
@Transactional(propagation=Propagation.NOT_SUPPORTED,readOnly=true)
public void func(){
//...
}
//事务超时秒数,默认-1,永不超时
@Transactional(timeout = 600)
public void func(){
//...
}
//事务隔离级别
//Isolation.DEFAULT默认的隔离级别,使用数据库默认的事务隔离级别
//Isolation.READ_UNCOMMITTED 这是事务最低的隔离级别,它充许令外一个事务可以看到这个事务未提交的数据。这种隔离级别会产生脏读,不可重复读和幻像读。
//Isolation.READ_COMMITTED 保证一个事务修改的数据提交后才能被另外一个事务读取。另外一个事务不能读取该事务未提交的数据
//Isolation.REPEATABLE_READ 这种事务隔离级别可以防止脏读,不可重复读。但是可能出现幻像读。它除了保证一个事务不能读取另一个事务未提交的数据外,还保证了避免下面的情况产生(不可重复读)。
//Isolation.SERIALIZABLE 这是花费最高代价但是最可靠的事务隔离级别。事务被处理为顺序执行。除了防止脏读,不可重复读外,还避免了幻像读。
@Transactional(isolation = Isolation.DEFAULT)
public void func(){
//...
}