spring+mybatis 事務 配置與使用

一. springmvc註解事務

之前一直有用事務,但是之前都只算使用。今天有才有空深入瞭解一下事務的配置使用。本人比較懶(哈哈哈),就先從懶人比較中意的註解事務開始吧。

怕有新手上路,所以spring.xml 和spring-mvc.xml都放出來

spring-mvc.xml

<?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:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <!-- 使用spring組件掃描@controller -->
    <context:component-scan base-package="com.zm.transaction.web"/>
    <!-- 通過annotation-driven可以替代下邊的處理器映射器和適配器 -->

    <!-- 視圖解析器 -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <!--<property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />-->
        <property name="prefix" value="/"/>
        <property name="suffix" value=".jsp"/>
    </bean>

    <mvc:default-servlet-handler/>
    <mvc:annotation-driven/>
</beans>
spring.xml

<?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:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">

    <!-- 導入配置文件 -->
    <context:property-placeholder location="classpath:properties/db.properties"/>

    <!-- druid 數據源 -->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
          init-method="init" destroy-method="close">
        <property name="driverClassName" value="${jdbc.driverClassName}" />
        <property name="url" value="${jdbc.url}" />
        <property name="username" value="${jdbc.username}" />
        <property name="password" value="${jdbc.password}" />
        <!-- 配置監控統計攔截的filters -->
        <property name="filters" value="stat" />
        <!-- 配置初始化大小、最小、最大 -->
        <property name="maxActive" value="20" />
        <property name="initialSize" value="1" />
        <property name="minIdle" value="1" />
        <!-- 配置獲取連接等待超時的時間 -->
        <property name="maxWait" value="60000" />
        <!-- 配置間隔多久才進行一次檢測,檢測需要關閉的空閒連接,單位是毫秒 -->
        <property name="timeBetweenEvictionRunsMillis" value="60000" />
        <!-- 配置一個連接在池中最小生存的時間,單位是毫秒 -->
        <property name="minEvictableIdleTimeMillis" value="300000" />
        <property name="testWhileIdle" value="true" />
        <property name="testOnBorrow" value="false" />
        <property name="testOnReturn" value="false" />
        <!-- 打開PSCache,並且指定每個連接上PSCache的大小 -->
        <property name="poolPreparedStatements" value="true" />
        <property name="maxOpenPreparedStatements" value="20" />
    </bean>

    <!-- 掃描mybatis 配置文件-->
    <bean name="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="typeAliasesPackage" value="com.zm.transaction.entity" />
        <property name="mapperLocations" value="classpath:mapper/*Mapper.xml" />
    </bean>
    <!-- 掃描Mapper 配置文件-->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.zm.transaction.mapper" />
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
    </bean>

    <!-- 添加事務註解支持 -->
    <tx:annotation-driven transaction-manager="txManager"/>
    <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <bean id="userService" class="com.zm.transaction.service.impl.UserServiceImpl">
    </bean>
</beans>

然後在就是在service實現中添加註解了,在我這裏就是上面的 com.zm.transaction.service.impl.UserServiceImpl類,@Transactional  有兩種用法:

(1)把這個註解放在類名稱上面了,這樣你配置的這個@Transactional 對這個類中的所有public方法都起作用. 
(2)@Transactional 方法方法名上,只對這個方法有作用,同樣必須是public的方法

我是使用在方法上註解的,並且使用了異常回滾。當insertUser成功時拋出異常,不執行insertRole。但是查詢數據庫insertUser插入的數據也被回滾了。

//@Service("userService")沒有手動配置
public class UserServiceImpl implements UserService {
    @Autowired
    private UserMapper userMapper;//這裏的mapper是我的dao層,上面有配置所以可以自動加載

    @Override
    @Transactional (rollbackFor=RuntimeException.class)
    public int addUser(User user) throws Exception {
        if(userMapper.insertUser(user) != 0)//如果插入成功,則拋出異常
            throw new RuntimeException(" ");//用來測試事務的異常
        userMapper.insertRole("會員","會員菜單");
        return 1;
    }
}

@Transactional還有其他的功能

超時: 
@Transactional(timeout=30) //默認是30秒

異常回滾: 
指定單一異常類:@Transactional(rollbackFor=RuntimeException.class)

指定多個異常類:@Transactional(rollbackFor={RuntimeException.class, Exception.class}) 
該屬性用於設置需要進行回滾的異常類數組,當方法中拋出指定異常數組中的異常時,則進行事務回滾。

正常的情況下也可以回滾:

TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();

只讀: 
@Transactional(readOnly=true) 
該屬性用於設置當前事務是否爲只讀事務,設置爲true表示只讀,false則表示可讀寫,默認值爲false。


二.非註解事務配置

其實非註解事務只要在spring.xml裏把配置改一下就行了,重複的配置就不在展示了,下面是需要改動

<?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:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">

    <!-- 添加事務註解支持 --> <!-- 刪除下面這一行 -->
    <!--<tx:annotation-driven transaction-manager="txManager"/>-->
    <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <!-- 添加以下配置 -->
    <tx:advice id="txAdvice" transaction-manager="txManager">
        <tx:attributes><!-- method name 需要與你的方法名前綴相同 -->
            <tx:method name="get*" read-only="true" />
            <tx:method name="add*" propagation="REQUIRED" isolation="READ_COMMITTED"
                       rollback-for="java.lang.RuntimeException" />
            <tx:method name="update*" />
        </tx:attributes>
    </tx:advice>
    <aop:config><!-- 括號內配置你的service所在包 -->
        <aop:pointcut id="serviceMethod" expression="execution(* com.zm.transaction.service.impl.*.*(..))" />
        <aop:advisor advice-ref="txAdvice" pointcut-ref="serviceMethod" />
    </aop:config>
</beans>
用過一種再是用另一種是不是很快上手,我就寫這麼多了,如果有什麼錯誤歡迎批評指正。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章