spring事务管理-Transaction模板(了解)
生活随笔
收集整理的這篇文章主要介紹了
spring事务管理-Transaction模板(了解)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
那就迫切的需要事務來進行管理了,給大家演示在Spring中,要給咱們Service加事務,怎么加,現在是不是還沒有加事務的,現在沒有加事務,怎么加,我們要演示三種方式,三種方式 演示完,Spring管理事務方式,這三種方式分別是,編碼式,其中編碼式我要把它標成是,綠色,這個編碼式你可以理解為觀光代碼,以后咱們不會用的,然后就是xml的配置式,括號aop,還有 一個是注解配置,也是屬于AOP的,紫色,明白是啥意思不,這個綠色話看著好玩,紫色是你們未來,以后都是這種紫色的這種方式,就這樣了,這是你們的final版,這是final版的,先來看輕松地,沒用的編碼式,顧名思義,你得在代碼里編寫事務,那這樣缺點在沒有寫你就知道,我有10個業務方法的話,我就在10個里面用事務管理的編碼,先來說一下步驟,這個步驟的話這樣,他們共有的我提取到外面,準備工作第一步,別忘了剛才咱們說的,事務管理器,接口不行,你得說實現類,咱們說這個是事務的核心,不管用三種方式的哪一種,都得把Manager給加上,所以這里的話,第一個,將核心事務管理器,配置到Spring容器,第一步寫完咱們就做一下,這里寫一個bean,然后呢,class屬性,DataSourceTransactionManager,咱們就把DataSourceTransactionManager用進來,然后前面給他來一個名字,name等于transactionManager,這個transactionManager是Spring操作事務的核心,那你說他有沒有依賴呢,他依賴是誰,能想到嗎,事務的操作,依賴誰,還要問嗎,你直接就能夠想到的,這個哥們顯然是依賴誰,是不是dataSource,為啥依賴dataSource,那咱們剛才說了半天,操作事務,你怎么打開,connection.setAutoCommit,false,提交你事務咋提交,connection.commit,那這個哥們負責調這些方法,手頭得有connection,是不是這個意思,那connection從哪里來,是不是連接池來的,知道啥意思,依賴關系就是這樣,知道啥意思不,你說你要去花錢,那我問你依賴啥,錢,是不是依賴錢,連接池,操作咱們事務的操作,那你操作事務,是不是得有連接事務的操作,沒連接你封裝什么,知道啥意思,所以他依賴于dataSource,這理解啥意思不,所以這東西,事務的核心管理器,然后這里面封裝了所有事務操作,依賴于咱們的連接池,有了核心事務管理器之后,那咱們編碼式操作事務,需要使用一個事務模板對象,這個模板對象是直接配上的,事務模板對象,name,class,TransactionTemplate,這個咱們復制,這個transactionTemplate,這個是事務模塊,這jdbc模板道理一樣,他把事務操作給你封裝進去了,那就是你要想控制事務的話,一會在咱們的service里面,需要調事務的這個方法,你可以把事務加進去,那事務模板也有依賴關系,它依賴于誰,這里只是調方法,所以他是需要transactionManager的,ref等于transactionManager,這樣的話事務模板有了,那編碼式的事務,把tt屬性注入進來,ref叫做transactionTemplate,這個注入進來,然后接下來在service當中,寫代碼就是tt點,調用它的execute方法,然后這個execute方法,需要你傳入一個接口,TransactionCallback,那這個TransactionCallback我看一下,他的子類叫做TransactionCallbackWithoutResult,這個TransactionTemplate,它是把事務打開和關閉的調用,給你封裝好了,然后你只需要告訴他,你打算把什么操作納入到事務管理當中就可以了,模板他已經封裝好了,什么時候打開事務,什么時候關閉事務,什么時候回滾事務,你只需要告訴模板,你需要干嘛就可以了,那你怎么告訴模板你需要干啥呢,就是實現這個接口,然后這里面有這個方法,當然這里匿名內部類訪問外部的需要加final,我寫一個偽代碼,execute方法大概就是長這樣的,首先它第一步打開,打開花事務,然后第二步調用這個方法,執行你傳進去的代碼,接下來第三步,提交事務,然后你這個方法有異常的話,調你這個方法的時候會加一個try catch,如果出異常的話,它會把你這個事務進行回滾,知道啥意思不,所以說白了,打開事務和提交事務代碼已經封裝好了,這樣的話你代碼就在事務環境內了,看明白啥意思不,啥叫模板,就是這些代碼是固定的,那這樣的話事務就已經加完了,就這么簡單,是不是可以執行一下了,咱們把數據庫復位,現在轉100塊錢,現在沒有異常,先看沒有異常執行成不成功,是不是沒有問題,是不是900和1100,接下來咱們造一個異常,看模板好不好使,造異常是不是把1除以0打開,這回再到Demo這兒,再運行這個方法,這個方法肯定報錯,是不是by zero,除0,那主要是看事務的問題,如果還是900和1100就對了,是這個效果,這樣就是通過編碼式來控制事務,說了這是一個觀光代碼,因為這樣的話你想,如果方法有10個,你這個execute要調10次,雖然你不用手寫打開關閉事務的代碼了,但是跟以前一樣,每一個業務方法里面都調這個方法,是不是麻煩,所以這是咱們的觀光代碼
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd "><!-- 指定spring讀取db.properties配置 -->
<context:property-placeholder location="classpath:db.properties" /><!-- 事務核心管理器,封裝了所有事務操作. 依賴于連接池 -->
<bean name="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager" ><property name="dataSource" ref="dataSource" ></property>
</bean><!-- 事務模板對象 -->
<bean name="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate" ><property name="transactionManager" ref="transactionManager" ></property>
</bean><!-- 1.連接池 -->
<bean name="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" ><property name="jdbcUrl" value="${jdbc.jdbcUrl}" ></property><property name="driverClass" value="${jdbc.driverClass}" ></property><property name="user" value="${jdbc.user}" ></property><property name="password" value="${jdbc.password}" ></property>
</bean><!-- 2.Dao-->
<bean name="accountDao" class="com.learn.dao.AccountDaoImpl" ><property name="dataSource" ref="dataSource" ></property>
</bean>
<!-- 3.Service-->
<bean name="accountService" class="com.learn.service.AccountServiceImpl" ><property name="ad" ref="accountDao" ></property><property name="tt" ref="transactionTemplate" ></property>
</bean> </beans>
package com.learn.dao;public interface AccountDao {//加錢void increaseMoney(Integer id,Double money);//減錢void decreaseMoney(Integer id,Double money);
}
package com.learn.dao;import org.springframework.jdbc.core.support.JdbcDaoSupport;public class AccountDaoImpl extends JdbcDaoSupport implements AccountDao {@Overridepublic void increaseMoney(Integer id, Double money) {getJdbcTemplate().update("update t_account set money = money+? where id = ? ", money,id);}@Overridepublic void decreaseMoney(Integer id, Double money) {getJdbcTemplate().update("update t_account set money = money-? where id = ? ", money,id);}}
package com.learn.service;public interface AccountService {//轉賬方法void transfer(Integer from,Integer to,Double money);}
package com.learn.service;import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;import com.learn.dao.AccountDao;@Transactional(isolation=Isolation.REPEATABLE_READ,propagation=Propagation.REQUIRED,readOnly=true)
public class AccountServiceImpl implements AccountService {private AccountDao ad ;private TransactionTemplate tt;@Overridepublic void transfer(final Integer from,final Integer to,final Double money) {tt.execute(new TransactionCallbackWithoutResult() {@Overrideprotected void doInTransactionWithoutResult(TransactionStatus arg0) {//減錢ad.decreaseMoney(from, money);int i = 1/0;//加錢ad.increaseMoney(to, money);}});// 1.打開事務// 2.調用doInTransactionWithoutResult方法// 3.提交事務}public void setAd(AccountDao ad) {this.ad = ad;}public void setTt(TransactionTemplate tt) {this.tt = tt;}}
package com.learn.tx;import javax.annotation.Resource;import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;import com.learn.service.AccountService;@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class Demo {@Resource(name="accountService")private AccountService as;@Testpublic void fun1(){as.transfer(1, 2, 100d);}
}
?
總結
以上是生活随笔為你收集整理的spring事务管理-Transaction模板(了解)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: spring事务管理-演示事务的环境准备
- 下一篇: spring事务管理-xml配置aop事