Spring事务管理

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);

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值