Spring 事务模型
Spring的事务传播行为:
1.PROPAGATION_REQUIRED:必须在事务内执行,如果当前存在事务,就加入到当前事务中;如果当前没有事务,就创建一个新事务。这是Spring默认的事务传播行为。
2.PROPAGATION_SUPPORTS:支持当前事务,当如果没有事务,也可以以非事务方式执行。
3.PROPAGATION_MANDATORY:必须在当前事务内执行,如果当前没有事务,就直接抛出异常。
4.PROPAGATION_REQUIRES_NEW:总是创建一个事务,如果当前存在事务,就把当前事务挂起,知道新事务执行完毕。
5.PROPAGATION_NOT_SUPPORTED:不能在事务环境下执行,如果当前存在事务,就把当前事务挂起。
6.PROPAGATION_NEVER:不能在事务环境下执行,如果当前存在事务,就直接抛出异常。
7.PROPAGATION_NESTED:必须在事务内执行,如果当前存在事务,则在嵌套内执行;如果当前没有事务,则执行与PROPAGATION_REQUIRED类似的操作。
Spring 事务包括编程式和声名式事务管理,主要说一下声名式
<!-- 定义BookDao -->
<bean id="bookDaoTarget" class="example.chapter6.BookDaoImpl">
<property name="dataSource" ref="dataSource" />
</bean>
<!-- 封装为事务的BookDao -->
<bean id="bookDao" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="target" ref="bookDaoTarget" />
<property name="transactionManager" ref="transactionManager" />
<property name="transactionAttributes">
<props>
<!-- 对以query开头的方法要求只读事务 -->
<prop key="query*">PROPAGATION_REQUIRED,readOnly</prop>
<!-- 对于其他方法要求事务 -->
<prop key="*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>
默认情况下,Spring只在RuntimeExceptin异常或Error抛出时回滚事务,如果抛出了CheckedException,Spring仍会提交事务。如果需要在CheckedException异常抛出时也回滚事务,就需要在TransactionProxyFactoryBean配置中显示的将每个CheckedException都添加进来。
<prop key="*">PROPAGATION_REQUIRED,-RemoteException,-SockectException</prop>
很明显,这样的方式客户端依然可以绕过事务管理,于是可以这样,
<?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.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-2.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.0.xsd"
>
<!-- 定义DataSource -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="org.hsqldb.jdbcDriver" />
<property name="url" value="jdbc:hsqldb:mem:bookstore" />
<property name="username" value="sa" />
<property name="password" value="" />
</bean>
<!-- 定义TransactionManager -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager" >
<property name="dataSource" ref="dataSource" />
</bean>
<!-- 定义BookDao -->
<bean id="bookDao" class="example.chapter6.BookDaoImpl">
<property name="dataSource" ref="dataSource" />
</bean>
<!-- 将BookDao封装成具有事务功能 -->
<!-- 声明TxAdvice -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<!-- 对以query开头的方法要求只读事务 -->
<tx:method name="query*" read-only="true" />
<!-- 对于其他方法要求事务 -->
<tx:method name="*" rollback-for="java.io.IOException" />
</tx:attributes>
</tx:advice>
<aop:config>
<!-- 使用AspectJ语法定义Pointcut -->
<aop:pointcut id="bookDaoOperation" expression="execution(* example.chapter6.BookDao.*(..))" />
<!-- 织入 -->
<aop:advisor advice-ref="txAdvice" pointcut-ref="bookDaoOperation" />
</aop:config>
</beans>
另外,还可以使用Java5的Annotation简化配置
<?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:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-2.0.xsd"
>
<!-- 定义DataSource -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="org.hsqldb.jdbcDriver" />
<property name="url" value="jdbc:hsqldb:mem:bookstore" />
<property name="username" value="sa" />
<property name="password" value="" />
</bean>
<!-- 定义TransactionManager -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager" >
<property name="dataSource" ref="dataSource" />
</bean>
<!-- 定义BookDao -->
<bean id="bookDao" class="example.chapter6.BookDaoImpl">
<property name="dataSource" ref="dataSource" />
</bean>
<!-- 将所有具有@Transactional注解的Bean自动配置为声明式事务支持 -->
<tx:annotation-driven transaction-manager="transactionManager"/>
</beans>
这样,接口结果如下:
import java.util.List;
import org.springframework.transaction.annotation.Transactional;
@Transactional
public interface BookDao {
@Transactional(readOnly=true)
Book query(String id);
@Transactional(readOnly=true)
List<Book> queryAll();
void insert(Book book);
void update(Book book);
void delete(Book book);
}
5万+

被折叠的 条评论
为什么被折叠?



