一. 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>
用過一種再是用另一種是不是很快上手,我就寫這麼多了,如果有什麼錯誤歡迎批評指正。