您好,登錄后才能下訂單哦!
本篇內(nèi)容介紹了“Spring怎么使用注解和配置文件配置事務(wù)”的有關(guān)知識(shí),在實(shí)際案例的操作過(guò)程中,不少人都會(huì)遇到這樣的困境,接下來(lái)就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!
使用注解配置事務(wù):
package com.atguigu.spring.tx; public interface BookShopDao { //根據(jù)書(shū)號(hào)獲取書(shū)的單價(jià) public int findBookPriceByIsbn(String isbn); //更新數(shù)的庫(kù)存. 使書(shū)號(hào)對(duì)應(yīng)的庫(kù)存 - 1 public void updateBookStock(String isbn); //更新用戶(hù)的賬戶(hù)余額: 使 username 的 balance - price public void updateUserAccount(String username, int price); }
package com.atguigu.spring.tx; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Repository; @Repository("bookShopDao") public class BookShopDaoImpl implements BookShopDao { @Autowired private JdbcTemplate jdbcTemplate; @Override public int findBookPriceByIsbn(String isbn) { String sql = "SELECT price FROM book WHERE isbn = ?"; return jdbcTemplate.queryForObject(sql, Integer.class, isbn); } @Override public void updateBookStock(String isbn) { //檢查書(shū)的庫(kù)存是否足夠, 若不夠, 則拋出異常 String sql2 = "SELECT stock FROM book_stock WHERE isbn = ?"; int stock = jdbcTemplate.queryForObject(sql2, Integer.class, isbn); if(stock == 0){ throw new BookStockException("庫(kù)存不足!"); } String sql = "UPDATE book_stock SET stock = stock -1 WHERE isbn = ?"; jdbcTemplate.update(sql, isbn); } @Override public void updateUserAccount(String username, int price) { //驗(yàn)證余額是否足夠, 若不足, 則拋出異常 String sql2 = "SELECT balance FROM account WHERE username = ?"; int balance = jdbcTemplate.queryForObject(sql2, Integer.class, username); if(balance < price){ throw new UserAccountException("余額不足!"); } String sql = "UPDATE account SET balance = balance - ? WHERE username = ?"; jdbcTemplate.update(sql, price, username); } }
package com.atguigu.spring.tx; public interface BookShopService { public void purchase(String username, String isbn); }
事務(wù)配置的核心部分:
package com.atguigu.spring.tx; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Isolation; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; @Service("bookShopService") public class BookShopServiceImpl implements BookShopService { @Autowired private BookShopDao bookShopDao; //添加事務(wù)注解 //1.使用 propagation 指定事務(wù)的傳播行為, 即當(dāng)前的事務(wù)方法被另外一個(gè)事務(wù)方法調(diào)用時(shí) //REQUIRED:為默認(rèn)取值, 被調(diào)用的事務(wù)一個(gè)執(zhí)行失敗整個(gè)大事務(wù)就回滾 //REQUIRES_NEW:調(diào)用的事務(wù)如果執(zhí)行成功就保存結(jié)果不會(huì)被回滾,其他事務(wù)執(zhí)行失敗不會(huì)影響到它 //2.使用 isolation 指定事務(wù)的隔離級(jí)別, 最常用的取值為 READ_COMMITTED //3.默認(rèn)情況下 Spring 的聲明式事務(wù)對(duì)所有的運(yùn)行時(shí)異常進(jìn)行回滾. 也可以通過(guò)對(duì)應(yīng)的 //屬性進(jìn)行設(shè)置. 通常情況下取默認(rèn)值即可. //4.使用 readOnly 指定事務(wù)是否為只讀. 表示這個(gè)事務(wù)只讀取數(shù)據(jù)但不更新數(shù)據(jù), //這樣可以幫助數(shù)據(jù)庫(kù)引擎優(yōu)化事務(wù). 若方法只讀取數(shù)據(jù)庫(kù)值, 應(yīng)設(shè)置 readOnly=true //5.使用 timeout 指定事務(wù)最多可以占用的時(shí)間,若超過(guò)時(shí)間則強(qiáng)制回滾 // @Transactional(propagation=Propagation.REQUIRES_NEW, // isolation=Isolation.READ_COMMITTED, // noRollbackFor={UserAccountException.class}) @Transactional(propagation=Propagation.REQUIRES_NEW, isolation=Isolation.READ_COMMITTED, readOnly=false, timeout=3) @Override public void purchase(String username, String isbn) { try { Thread.sleep(5000); } catch (InterruptedException e) {} //1. 獲取書(shū)的單價(jià) int price = bookShopDao.findBookPriceByIsbn(isbn); //2. 更新數(shù)的庫(kù)存 bookShopDao.updateBookStock(isbn); //3. 更新用戶(hù)余額 bookShopDao.updateUserAccount(username, price); } }
package com.atguigu.spring.tx; import java.util.List; public interface Cashier { public void checkout(String username, List<String> isbns); }
package com.atguigu.spring.tx; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @Service("cashier") public class CashierImpl implements Cashier { @Autowired private BookShopService bookShopService; @Transactional @Override public void checkout(String username, List<String> isbns) { for(String isbn: isbns){ bookShopService.purchase(username, isbn); } } }
package com.atguigu.spring.tx; import static org.junit.Assert.*; import java.util.Arrays; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class SpringTransactionTest { private ApplicationContext ctx = null; private BookShopDao bookShopDao = null; private BookShopService bookShopService = null; private Cashier cashier = null; { ctx = new ClassPathXmlApplicationContext("applicationContext.xml"); bookShopDao = ctx.getBean(BookShopDao.class); bookShopService = ctx.getBean(BookShopService.class); cashier = ctx.getBean(Cashier.class); } @Test public void testTransactionlPropagation(){ cashier.checkout("AA", Arrays.asList("1001", "1002")); } @Test public void testBookShopService(){ bookShopService.purchase("AA", "1001"); } @Test public void testBookShopDaoUpdateUserAccount(){ bookShopDao.updateUserAccount("AA", 200); } @Test public void testBookShopDaoUpdateBookStock(){ bookShopDao.updateBookStock("1001"); } @Test public void testBookShopDaoFindPriceByIsbn() { System.out.println(bookShopDao.findBookPriceByIsbn("1001")); } }
BookStockException、UserAccountException為自定義異常類(lèi)!
配置文件:
<?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/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd"> <context:component-scan base-package="com.atguigu.spring"></context:component-scan> <!-- 導(dǎo)入資源文件 --> <context:property-placeholder location="classpath:db.properties"/> <!-- 配置 C3P0 數(shù)據(jù)源 --> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="user" value="${jdbc.user}"></property> <property name="password" value="${jdbc.password}"></property> <property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property> <property name="driverClass" value="${jdbc.driverClass}"></property> <property name="initialPoolSize" value="${jdbc.initPoolSize}"></property> <property name="maxPoolSize" value="${jdbc.maxPoolSize}"></property> </bean> <!-- 配置 Spirng 的 JdbcTemplate --> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="dataSource"></property> </bean> <!-- 配置 NamedParameterJdbcTemplate, 該對(duì)象可以使用具名參數(shù), 其沒(méi)有無(wú)參數(shù)的構(gòu)造器, 所以必須為其構(gòu)造器指定參數(shù) --> <bean id="namedParameterJdbcTemplate" class="org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate"> <constructor-arg ref="dataSource"></constructor-arg> </bean> <!-- 配置事務(wù)管理器 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"></property> </bean> <!-- 啟用事務(wù)注解 --> <tx:annotation-driven transaction-manager="transactionManager"/> </beans>
配置文件(使用配置文件配置事務(wù),以上類(lèi)的注解需要全部刪除):
<?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/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd"> <context:component-scan base-package="com.atguigu.spring"></context:component-scan> <!-- 導(dǎo)入資源文件 --> <context:property-placeholder location="classpath:db.properties"/> <!-- 配置 C3P0 數(shù)據(jù)源 --> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="user" value="${jdbc.user}"></property> <property name="password" value="${jdbc.password}"></property> <property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property> <property name="driverClass" value="${jdbc.driverClass}"></property> <property name="initialPoolSize" value="${jdbc.initPoolSize}"></property> <property name="maxPoolSize" value="${jdbc.maxPoolSize}"></property> </bean> <!-- 配置 Spirng 的 JdbcTemplate --> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="dataSource"></property> </bean> <!-- 配置 bean --> <bean id="bookShopDao" class="com.atguigu.spring.tx.xml.BookShopDaoImpl"> <property name="jdbcTemplate" ref="jdbcTemplate"></property> </bean> <bean id="bookShopService" class="com.atguigu.spring.tx.xml.service.impl.BookShopServiceImpl"> <property name="bookShopDao" ref="bookShopDao"></property> </bean> <bean id="cashier" class="com.atguigu.spring.tx.xml.service.impl.CashierImpl"> <property name="bookShopService" ref="bookShopService"></property> </bean> <!-- 1. 配置事務(wù)管理器 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"></property> </bean> <!-- 2. 配置事務(wù)屬性 --> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes> <!-- 根據(jù)方法名指定事務(wù)的屬性 --> <tx:method name="purchase" propagation="REQUIRES_NEW"/> <tx:method name="get*" read-only="true"/> <tx:method name="find*" read-only="true"/> <tx:method name="*"/> </tx:attributes> </tx:advice> <!-- 3. 配置事務(wù)切入點(diǎn), 以及把事務(wù)切入點(diǎn)和事務(wù)屬性關(guān)聯(lián)起來(lái) --> <aop:config> <aop:pointcut expression="execution(* com.atguigu.spring.tx.xml.service.*.*(..))" id="txPointCut"/> <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointCut"/> </aop:config> </beans>
“Spring怎么使用注解和配置文件配置事務(wù)”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。