......
<context:annotation-config />
<context:component-scan base-package="com.bluesky" />
<tx:annotation-driven transaction-manager="transactionManager" />
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="configLocation" value="classpath:hibernate.cfg.xml" />
<property name="configurationClass" value="org.hibernate.cfg.AnnotationConfiguration" />
</bean>
<!-- 定義事務管理器(聲明式的事務) -->
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
@Transactional
@Component("userDao")
public class UserDaoImpl extends HibernateDaoSupport implements UserDao {
public List<User> listUsers() {
return this.getSession().createQuery("from User").list();
}
......
}
傳播屬性
Propagation propagation() default Propagation.REQUIRED;
- PROPAGATION_REQUIRED--支持當前事務,如果當前沒有事務,就新建一個事務。這是最常見的選擇。
- PROPAGATION_SUPPORTS--支持當前事務,如果當前沒有事務,就以非事務方式執行。
- PROPAGATION_MANDATORY--支持當前事務,如果當前沒有事務,就拋出異常。
- PROPAGATION_REQUIRES_NEW--新建事務,如果當前存在事務,把當前事務掛起。
- PROPAGATION_NOT_SUPPORTED--以非事務方式執行操作,如果當前存在事務,就把當前事務掛起。
- PROPAGATION_NEVER--以非事務方式執行,如果當前存在事務,則拋出異常。
ServiceA {
//事務屬性配置爲 PROPAGATION_REQUIRED
void methodA() {
try {
//savepoint
ServiceB.methodB(); //PROPAGATION_NESTED 級別
} catch (SomeException) {
// 執行其他業務, 如 ServiceC.methodC();
}
}
}
隔離級別
/**
* Use the default isolation level of the underlying datastore.
* All other levels correspond to the JDBC isolation levels.
* @see java.sql.Connection
*/
int ISOLATION_DEFAULT = -1;
READ-ONLY
關於只讀事務和無事務
- 如果你一次執行單條查詢語句,則沒有必要啓用事務支持,數據庫默認支持SQL執行期間的讀一致性;
- 如果你一次執行多條查詢語句,例如統計查詢,報表查詢,在這種場景下,多條查詢SQL必須保證整體的讀一致性,否則,在前條SQL查詢之後,後條SQL查詢之前,數據被其他用戶改變,則該次整體的統計查詢將會出現讀數據不一致的狀態,此時,應該啓用事務支持。 【注意是一次執行多次查詢來統計某些信息,這時爲了保證數據整體的一致性,要用只讀事務】
多數據源
<tx:annotation-driven transaction-manager="transactionManager"/>
<tx:annotation-driven transaction-manager="transactionManagerSlave"/>
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com.api.example.pub.dao"/> <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/> </bean>
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Transactional {
/**
* A qualifier value for the specified transaction.
* <p>May be used to determine the target transaction manager,
* matching the qualifier value (or the bean name) of a specific
* {@link org.springframework.transaction.PlatformTransactionManager}
* bean definition.
*/
String value() default "";