Spring事務(wù)有幾種實現(xiàn)方法?針對這個問題,今天小編總結(jié)這篇有關(guān)云服務(wù)器的文章,可供感興趣的小伙伴們參考借鑒,希望對大家有所幫助。
公司主營業(yè)務(wù):網(wǎng)站設(shè)計、網(wǎng)站制作、移動網(wǎng)站開發(fā)等業(yè)務(wù)。幫助企業(yè)客戶真正實現(xiàn)互聯(lián)網(wǎng)宣傳,提高企業(yè)的競爭能力。創(chuàng)新互聯(lián)建站是一支青春激揚、勤奮敬業(yè)、活力青春激揚、勤奮敬業(yè)、活力澎湃、和諧高效的團隊。公司秉承以“開放、自由、嚴謹、自律”為核心的企業(yè)文化,感謝他們對我們的高要求,感謝他們從不同領(lǐng)域給我們帶來的挑戰(zhàn),讓我們激情的團隊有機會用頭腦與智慧不斷的給客戶帶來驚喜。創(chuàng)新互聯(lián)建站推出紫金免費做網(wǎng)站回饋大家。
Spring提供了一個事務(wù)管理接口,PlatformTransactionManager它里面提供了常用的事務(wù)操作的方法:
public interface PlatformTransactionManager {
//獲取事務(wù)狀態(tài)信息
TransactionStatus getTransaction(@Nullable TransactionDefinition var1) throws TransactionException;
//提交事務(wù)
void commit(TransactionStatus var1) throws TransactionException;
//回滾事務(wù)
void rollback(TransactionStatus var1) throws TransactionException;
}
PlatformTransactionManager接口里面定義了提交,回滾等對事物操作的基本方法。
這里出現(xiàn)了兩個接口:
一:TransactionDefinition
它定義了事物的基本屬性
public interface TransactionDefinition {
//返回事物的傳播行為
int getPropagationBehavior();
//返回事務(wù)的隔離級別,事務(wù)管理器根據(jù)它來控制另外一個事務(wù)可以看到本事務(wù)內(nèi)的哪些數(shù)據(jù)。
int getIsolationLevel();
//返回事務(wù)必須在多少秒內(nèi)完成
int getTimeout();
//事務(wù)是否只讀,事務(wù)管理器能夠根據(jù)這個返回值進行優(yōu)化,確保事務(wù)是只讀的。
boolean isReadOnly();
}
事物的傳播行為表示一個方法被另一個方法調(diào)用時事物如何傳播。
我有一篇文章詳細的講解了事物傳播行為:
事物的隔離級別 我在這篇文章里有詳述:
getTimeout()返回事物的超時時間,事物的執(zhí)行會不同程度的鎖定表,如果時間過長,其它事物對表的操作就會受到影響,執(zhí)行超時以后事物就會回滾。
isReadOnly()返回事物是否只讀,如果事物只是去讀取數(shù)據(jù)庫我們可以把它設(shè)置為只讀,數(shù)據(jù)庫就可以進行相應(yīng)的優(yōu)化,提高執(zhí)行效率。
二:TransactionStatus
此接口提供了事物運行的具體狀態(tài)
public interface TransactionStatus extends SavepointManager, Flushable {
boolean isNewTransaction();//是否是新的事物
boolean hasSavepoint();//是否有恢復(fù)點
void setRollbackOnly();//設(shè)置為只回滾
boolean isRollbackOnly();//是否為只回滾
boolean isCompleted();//是否已完成
}在回滾或提交操作的時候需要這些事物的狀態(tài)作為參數(shù)。
PlatformTransactionManager只是一個事物管理的接口,我們真正要用的是該接口的實現(xiàn)類,如果你是用Jdbc或mybatis操作數(shù)據(jù)庫需要使用事務(wù)管理類:
org.springframework.jdbc.datasource.DataSourceTransactionManager
如果用的是Hibernate需要使用事物管理類:
org.springframework.orm.hibernate5.HibernateTransactionManager
在spring中實現(xiàn)事物通常有兩種方式:
一:基于 XML 的聲明式事務(wù)控制(配置方式):
通過轉(zhuǎn)賬的例子來說明:
數(shù)據(jù)庫:

第一步:導入依賴
<dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.0.2.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>5.0.2.RELEASE</version> </dependency> <dependency> <groupId>MySQL</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.46</version> </dependency>
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>5.0.2.RELEASE</version> </dependency>
<dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.8.7</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> <version>5.0.2.RELEASE</version> </dependency> </dependencies>
spring-tx是事物管理的依賴,因為spring的事物管理底層使用的是aop所以需要把aop的依賴aspectjweaver也導入進來。
第二步:創(chuàng)建 spring 的配置文件并導入約束
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd">
</beans>
第三步:創(chuàng)建Account實體類
第四步:編寫 Dao 接口和實現(xiàn)類
public interface IAccountDao {
//根據(jù)名稱查詢賬戶信息
Account findAccountByName(String name);
//更新賬戶信息
void updateAccount(Account account);
}
public class AccountDaoImpl implements IAccountDao {
@Autowired
private JdbcTemplate jt;
public Account findAccountByName(String name) {
List<Account> lst = jt.query("select * from account where name like ?",new BeanPropertyRowMapper<Account>(Account.class),name);
return lst.isEmpty()?null:lst.get(0);
}
public void updateAccount(Account account) {
jt.update("update account set money = ? where id = ? ",account.getMoney(),account.getId());
}
}第五步:編寫業(yè)務(wù)層接口和實現(xiàn)類
public interface IAccountService {
* 轉(zhuǎn)賬
* @param sourceName 轉(zhuǎn)出賬戶名稱
* @param targeName 轉(zhuǎn)入賬戶名稱
* @param money 轉(zhuǎn)賬金額
*/
void transfer(String sourceName,String targeName,Float money);//增刪改}
/**
* 賬戶的業(yè)務(wù)層實現(xiàn)類
*/
public class AccountServiceImpl implements IAccountService {
private IAccountDao accountDao;
public void transfer(String sourceName, String targeName, Float money) {
//1.根據(jù)名稱查詢兩個賬戶
Account source = accountDao.findAccountByName(sourceName);
Account target = accountDao.findAccountByName(targeName);
//2.修改兩個賬戶的金額
source.setMoney(source.getMoney()-money);//轉(zhuǎn)出賬戶減錢
target.setMoney(target.getMoney()+money);//轉(zhuǎn)入賬戶加錢
//3.更新兩個賬戶
accountDao.updateAccount(source);
int i=1/0;
accountDao.updateAccount(target);
}
}第六步:在配置文件中配置業(yè)務(wù)層和持久層
<context:component-scan base-package="cn.xh"></context:component-scan> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="dataSource"></property> </bean> <!-- 配置 service --> <bean id="accountService" class="cn.xh.service.AccountServiceImpl"> </bean> <!-- 配置 dao --> <bean id="accountDao" class="cn.xh.dao.AccountDaoImpl"> </bean> <!-- 配置數(shù)據(jù)源 --> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"></property> <property name="url" value="jdbc:mysql:///spring_demo01"></property> <property name="username" value="root"></property> <property name="password" value="123456"></property>
</bean>
第七步:配置事務(wù)
Spring事務(wù)是基于aop的關(guān)于aop我在這篇文章里有詳細的講解:
配置步驟:
1: 配置事務(wù)管理器:
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!-- 注入 DataSource -->
<property name="dataSource" ref="dataSource"></property>
</bean>
2:配置事務(wù)的通知引用事務(wù)管理器:
<tx:advice id="txAdvice" transaction-manager="transactionManager">
</tx:advice>
3:配置事務(wù)的屬性:
<!-- 配置事務(wù)的通知--> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <!-- 配置事務(wù)的屬性 isolation:用于指定事務(wù)的隔離級別。默認值是DEFAULT,表示使用數(shù)據(jù)庫的默認隔離級別。 propagation:用于指定事務(wù)的傳播行為。
read-only:用于指定事務(wù)是否只讀。只有查詢方法才能設(shè)置為true。默認值是false,表示讀寫。 timeout:用于指定事務(wù)的超時時間,默認值是-1,表示永不超時。如果指定了數(shù)值,以秒為單位。 rollback-for:用于指定一個異常,當產(chǎn)生該異常時,事務(wù)回滾,產(chǎn)生其他異常時,事務(wù)不回滾。沒有默認值。表示任何異常都回滾。 no-rollback-for:用于指定一個異常,當產(chǎn)生該異常時,事務(wù)不回滾,產(chǎn)生其他異常時事務(wù)回滾。沒有默認值。表示任何異常都回滾。 --> <tx:attributes> <tx:method name="*" propagation="REQUIRED" read-only="false"/> <tx:method name="find*" propagation="SUPPORTS" read-only="true"></tx:method> </tx:attributes> </tx:advice>
4:配置 AOP 切入點表達式:
<!-- 配置aop--> <aop:config> <!-- 配置切入點表達式--> <aop:pointcut id="pt1" expression="execution(* cn.xh.service.*.*(..))"></aop:pointcut> <!--建立切入點表達式和事務(wù)通知的對應(yīng)關(guān)系 --> <aop:advisor advice-ref="txAdvice" pointcut-ref="pt1"></aop:advisor> </aop:config>
我們看看這個配置:
<!-- 配置切入點表達式-->
<aop:pointcut id="pt1" expression="execution(* cn.xh.service.*.*(..))"></aop:pointcut>
說明對cn.xh.service下的所有類的所有方法加上事務(wù)。
再來看看這個配置:
<!-- 配置事務(wù)的通知--> <tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes> <tx:method name="*" propagation="REQUIRED" read-only="false"/> <tx:method name="find*" propagation="SUPPORTS" read-only="true"></tx:method> </tx:attributes> </tx:advice>
這個配置說明以find開頭的方法事務(wù)的傳播方式為SUPPORTS,為只讀,其它的方法事務(wù)傳播方式為REQUIRED,不是只讀。
好啦,現(xiàn)在可以測試啦:
@RunWith(SpringJUnit4Cla***unner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class serviceTest {
@Autowired
private IAccountService serviceImpl;
@Test
public void testDo(){
serviceImpl.transfer("%張%","%李%",1000f);
}
}從張三賬戶往李四賬戶轉(zhuǎn)1000,因為有除零錯誤,事務(wù)回滾,張三賬戶還是2000,李四賬戶還是3000.
再來看看事務(wù)實現(xiàn)的第二種方式
二:基于注解的配置方式
我們重點看一下事務(wù)的注解配置,其它同上。
配置步驟:
第一步:配置事務(wù)管理器并注入數(shù)據(jù)源
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
第二步:在業(yè)務(wù)層使用@Transactional 注解:
@Transactional(readOnly=true,propagation=Propagation.SUPPORTS)
public class AccountServiceImpl implements IAccountService {
@Autowired
private IAccountDao accountDao;
@Override
public Account findAccountById(Integer id) {
return accountDao.findAccountById(id);
}
@Override
@Transactional(readOnly=false,propagation=Propagation.REQUIRED)
public void transfer(String sourceName, String targeName, Float money) {
//1.根據(jù)名稱查詢兩個賬戶
Account source = accountDao.findAccountByName(sourceName);
Account target = accountDao.findAccountByName(targeName);
//2.修改兩個賬戶的金額
source.setMoney(source.getMoney()-money);//轉(zhuǎn)出賬戶減錢
target.setMoney(target.getMoney()+money);//轉(zhuǎn)入賬戶加錢
//3.更新兩個賬戶
accountDao.updateAccount(source);
//int i=1/0;
accountDao.updateAccount(target);
}
}
該注解的屬性和 xml 中的屬性含義一致,該注解可以出現(xiàn)在接口上,類上和方法上。
出現(xiàn)接口上,表示該接口的所有實現(xiàn)類都有事務(wù)支持。
出現(xiàn)在類上,表示類中所有方法有事務(wù)支持
出現(xiàn)在方法上,表示方法有事務(wù)支持。
以上三個位置的優(yōu)先級:方法>類>接口
第三步:在配置文件中開啟 spring 對注解事務(wù)的支持:
<tx:annotation-driven transaction-manager="transactionManager"/>
關(guān)于Spring事務(wù)實現(xiàn)方法就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,可以學到更多知識。如果喜歡這篇文章,不如把它分享出去讓更多的人看到。
網(wǎng)站名稱:Spring事務(wù)有幾種實現(xiàn)方法
分享地址:http://chinadenli.net/article38/ppdgpp.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供企業(yè)建站、動態(tài)網(wǎng)站、響應(yīng)式網(wǎng)站、做網(wǎng)站、網(wǎng)站建設(shè)、電子商務(wù)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)