SpringMVC+MyBatis 事務(wù)管理(實(shí)例)
前言
spring事務(wù)管理包含兩種情況,編程式事務(wù)、聲明式事務(wù)。而聲明式事務(wù)又包括基于注解@Transactional和tx+aop的方式。那么本文先分析編程式注解事務(wù)和基于注解的聲明式事務(wù)。 編程式事務(wù)管理使用TransactionTemplate或者PlatformTransactionManager。對(duì)于編程式事務(wù)spring推薦使用TransactionTemplate。
一、編程式事務(wù)
spring事務(wù)特性
spring中所有的事務(wù)策略類都繼承自org.springframework.transaction.PlatformTransactionManager接口
public interface PlatformTransactionManager {
TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException;
void commit(TransactionStatus status) throws TransactionException;
void rollback(TransactionStatus status) throws TransactionException;
}
編程式事務(wù)TransactionTemplate需要手動(dòng)在代碼中處理事務(wù),一般不推薦使用,也不符合spring的思想,因?yàn)樗苯玉詈洗a,但各有利弊。先看下TransactionTemplate的源碼。
public class TransactionTemplate extends DefaultTransactionDefinition
implements TransactionOperations, InitializingBean {
protected final Log logger = LogFactory.getLog(getClass());
private PlatformTransactionManager transactionManager;
public TransactionTemplate() {
}
public TransactionTemplate(PlatformTransactionManager transactionManager) {
this.transactionManager = transactionManager;
}
public TransactionTemplate(PlatformTransactionManager transactionManager, TransactionDefinition transactionDefinition) {
super(transactionDefinition);
this.transactionManager = transactionManager;
}
public void setTransactionManager(PlatformTransactionManager transactionManager) {
this.transactionManager = transactionManager;
}
public PlatformTransactionManager getTransactionManager() {
return this.transactionManager;
}
@Override
public void afterPropertiesSet() {
if (this.transactionManager == null) {
throw new IllegalArgumentException("Property 'transactionManager' is required");
}
}
@Override
public <T> T execute(TransactionCallback<T> action) throws TransactionException {
if (this.transactionManager instanceof CallbackPreferringPlatformTransactionManager) {
return ((CallbackPreferringPlatformTransactionManager) this.transactionManager).execute(this, action);
}
else {
TransactionStatus status = this.transactionManager.getTransaction(this);
T result;
try {
result = action.doInTransaction(status);
}
catch (RuntimeException ex) {
// Transactional code threw application exception -> rollback
rollbackOnException(status, ex);
throw ex;
}
catch (Error err) {
// Transactional code threw error -> rollback
rollbackOnException(status, err);
throw err;
}
catch (Throwable ex) {
// Transactional code threw unexpected exception -> rollback
rollbackOnException(status, ex);
throw new UndeclaredThrowableException(ex, "TransactionCallback threw undeclared checked exception");
}
this.transactionManager.commit(status);
return result;
}
}
private void rollbackOnException(TransactionStatus status, Throwable ex) throws TransactionException {
logger.debug("Initiating transaction rollback on application exception", ex);
try {
this.transactionManager.rollback(status);
}
catch (TransactionSystemException ex2) {
logger.error("Application exception overridden by rollback exception", ex);
ex2.initApplicationException(ex);
throw ex2;
}
catch (RuntimeException ex2) {
logger.error("Application exception overridden by rollback exception", ex);
throw ex2;
}
catch (Error err) {
logger.error("Application exception overridden by rollback error", ex);
throw err;
}
}
}
從上面的代碼可以看到核心方法是execute,該方法入?yún)ransactionCallback<T>。查看TransactionCallback源碼:
public interface TransactionCallback<T> {
T doInTransaction(TransactionStatus status);
}
那么以上兩個(gè)源碼可以確定我們使用編程式事務(wù)管理的方式也就是自己需要重寫doInTransaction()。OK,那么我們手動(dòng)使用TransactionTemplate處理下。
1、先配置transactionmanager
<!--事務(wù)管理器 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean>
2、配置transactionTemplate
<!--編程式事務(wù),推薦使用TransactionTemplate--> <bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate"> <property name="transactionManager" ref="transactionManager"/> </bean>
3、業(yè)務(wù)代碼處理
@Autowired
private TransactionTemplate transactionTemplate;
public int insertUser2(final User user) {
Integer i= (Integer) this.transactionTemplate.execute(new TransactionCallback() {
public Object doInTransaction(TransactionStatus transactionStatus) {
int i = userMapper.insertUser(user);
if (i > 0) {
System.out.println("success");
}
int j = 10 / 0;
return i;
}
});
return i;
}
業(yè)務(wù)代碼中我們使用by zero的異常故意拋出,你會(huì)發(fā)現(xiàn)能繼續(xù)打印success,當(dāng)你斷點(diǎn)debug時(shí),你會(huì)發(fā)現(xiàn)數(shù)據(jù)庫(kù)一直是鎖定狀態(tài),直到你程序執(zhí)行完。如下圖:

二、基于Transactional注解的事務(wù)管理
當(dāng)前應(yīng)該是使用最清爽的事務(wù)管理方式了,也符合spring的理念,非入侵代碼的方式。
1、配置
<!--事務(wù)管理器 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean> <!-- 使用注解事務(wù),需要添加Transactional注解屬性 --> <tx:annotation-driven transaction-manager="transactionManager"/> <!--啟用最新的注解器、映射器--> <mvc:annotation-driven/>
2、配置后只需要在要處理的地方加上Transactional注解,而且Transactional注解的方式可以應(yīng)用在類上,也可以應(yīng)用在方法上,當(dāng)然只針對(duì)public方法。
3、業(yè)務(wù)代碼處理
@Transactional
public int insertUser(User user) {
int i = userMapper.insertUser(user);
if (i > 0) {
System.out.println("success");
}
int j = 10 / 0;
return i;
}
總結(jié)
以上所述是小編給大家介紹的SpringMVC+MyBatis 事務(wù)管理,希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
相關(guān)文章
RestTemplate未使用線程池問(wèn)題的解決方法
今天給大家?guī)?lái)的是關(guān)于Springboot的相關(guān)知識(shí),文章圍繞著RestTemplate未使用線程池展開,文中有非常詳細(xì)的介紹及代碼示例,需要的朋友可以參考下2021-06-06
springboot整合cxf發(fā)布webservice以及調(diào)用的方法
這篇文章主要介紹了springboot整合cxf發(fā)布webservice以及調(diào)用的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-08-08
基于Java實(shí)現(xiàn)圖形驗(yàn)證碼工具類
這篇文章主要為大家詳細(xì)介紹了如何基于Java實(shí)現(xiàn)圖形驗(yàn)證碼工具類,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2024-11-11
詳解Spring學(xué)習(xí)總結(jié)——Spring實(shí)現(xiàn)AOP的多種方式
這篇文章主要介紹了詳解Spring學(xué)習(xí)總結(jié)——Spring實(shí)現(xiàn)AOP的多種方式,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-01-01
SpringBoot實(shí)現(xiàn)多文件上傳的詳細(xì)示例代碼
文件上傳中并沒有什么太多的知識(shí)點(diǎn),下面這篇文章主要給大家介紹了關(guān)于SpringBoot實(shí)現(xiàn)多文件上傳的詳細(xì)示例,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-03-03

