日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

spring控制事务:声明式事务(注解)

發(fā)布時間:2024/4/15 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 spring控制事务:声明式事务(注解) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

聲明式事務(wù)(注解)

spring聲明事務(wù)的方式,使用注解的方式

@Transactional

? 名稱:@Transactional
? 類型:方法注解,類注解,接口注解
? 位置:方法定義上方,類定義上方,接口定義上方
? 作用:設(shè)置當(dāng)前類/接口中所有方法或具體方法開啟事務(wù),并指定相關(guān)事務(wù)屬性
? 范例:

@Transactional( readOnly = false, timeout = -1, isolation = Isolation.DEFAULT, rollbackFor = {ArithmeticException.class, IOException.class}, noRollbackFor = {}, propagation = Propagation.REQUIRES_NEW )

tx:annotation-driven 標(biāo)簽用于開啟事務(wù)的注解驅(qū)動

? 名稱:tx:annotation-driven
? 類型:標(biāo)簽
? 歸屬:beans標(biāo)簽
? 作用:開啟事務(wù)注解驅(qū)動,并指定對應(yīng)的事務(wù)管理器
? 范例:

<tx:annotation-driven transaction-manager="txManager"/>

聲明式事務(wù)(純注解驅(qū)動)

@EnableTransactionManagement 這個注解就是代替上面的標(biāo)簽

? 名稱:@EnableTransactionManagement
? 類型:類注解
? 位置:Spring注解配置類上方
? 作用:開啟注解驅(qū)動,等同XML格式中的注解驅(qū)動
? 范例:

@Configuration @ComponentScan("com.fs") @PropertySource("classpath:jdbc.properties") @Import({JDBCConfig.class,MyBatisConfig.class,TransactionManagerConfig.class}) @EnableTransactionManagement public class SpringConfig { } public class TransactionManagerConfig { @Bean public PlatformTransactionManager getTransactionManager(@Autowired DataSource dataSource){ return new DataSourceTransactionManager(dataSource); } }

代碼演示(代碼中注釋為詳細(xì)解釋)

數(shù)據(jù)表account

構(gòu)建maven項目

pom文件

<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.fs</groupId><artifactId>day04_spring_AOP_Transaction_02</artifactId><version>1.0-SNAPSHOT</version><dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.1.9.RELEASE</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-test</artifactId><version>5.1.9.RELEASE</version></dependency><!-- jdbc--><dependency><groupId>org.springframework</groupId><artifactId>spring-jdbc</artifactId><version>5.1.9.RELEASE</version></dependency><!-- spring整合mybatis--><dependency><groupId>org.mybatis</groupId><artifactId>mybatis-spring</artifactId><version>2.0.1</version></dependency><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.5.5</version></dependency><!-- mysql--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.47</version></dependency><!--druid連接池--><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.1.20</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.12</version></dependency><!-- aop切面包--><dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.9.5</version></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><scope>test</scope></dependency></dependencies></project>

jdbc.properties

jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://192.168.93.132:3306/test jdbc.username=root jdbc.password=root

編寫配置類

SpringConfig

package com.fs.config;import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.EnableAspectJAutoProxy; import org.springframework.context.annotation.Import; import org.springframework.transaction.annotation.EnableTransactionManagement;//表示這個類是一個spring的配置類,并將其存入到ioc容器中 @Configuration /*開啟掃描注解的那些包 <!-- 啟動spring掃描注解的包,只掃描spring的注解--><context:component-scan base-package="com.fs"/>*/ @ComponentScan("com.fs") //引入其他的配置類 @Import({JdbcConfig.class,MybatisConfig.class,TransactionManagerConfig.class}) //開啟切面自動代理 @EnableAspectJAutoProxy //開啟聲明式事務(wù)管理 相當(dāng)于配置文件中的 <tx:annotation-driven transaction-manager="transactionManager"/> @EnableTransactionManagement public class SpringConfig { }

JdbcConfig

package com.fs.config;import com.alibaba.druid.pool.DruidDataSource; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.PropertySource;/* <!-- 引入properties--><context:property-placeholder location="classpath:jdbc.properties"/>*/ @PropertySource("classpath:jdbc.properties") public class JdbcConfig {//@Value("${Key}")@Value("${jdbc.driver}")private String driver;@Value("${jdbc.url}")private String url;@Value("${jdbc.username}")private String username;@Value("${jdbc.password}")private String password;/*<!-- 整合druid,把DruidDataSource交給spring管理--><bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"><property name="driverClassName" value="${jdbc.driver}"/><property name="url" value="${jdbc.url}"/><property name="username" value="${jdbc.username}"/><property name="password" value="${jdbc.password}"/></bean>*///將返回的DruidDataSource交給ioc管理@Beanpublic DruidDataSource getDruidDataSource(){//創(chuàng)建DruidDataSourceDruidDataSource druidDataSource = new DruidDataSource();//給屬性賦值,這個是上面從配置文件中依耐注入給屬性的druidDataSource.setDriverClassName(driver);druidDataSource.setUrl(url);druidDataSource.setUsername(username);druidDataSource.setPassword(password);//返回DruidDataSource,然后交給ioc管理return druidDataSource;} }

MybatisConfig

package com.fs.config;import org.mybatis.spring.SqlSessionFactoryBean; import org.mybatis.spring.mapper.MapperScannerConfigurer; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean;import javax.sql.DataSource;public class MybatisConfig {/*<!-- 配置MyBatis的會話工廠類 mybatis.spring 下的SqlSessionFactoryBean配置的sqlSessionFactory得到SqlSession,然后MyBatis從spring中拿到SqlSession.getMapper()去動態(tài)代理dao--><bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <!-- 給MyBatis配置鏈接池,依耐注入--><property name="dataSource" ref="dataSource"/> <!-- 配置別名掃描的包,被掃描的包下的類起的別名就是類名首字母小寫,用于mapper.xml文件中使用--><property name="typeAliasesPackage" value="com.fs.pojo"/></bean>*/@Beanpublic SqlSessionFactoryBean getSqlSessionFactoryBean(@Autowired DataSource dataSource){//創(chuàng)建sql會話工廠類 //這里@Autowired也是從ioc拿DataSourceSqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();//從ioc容器中取出jdbcConfig中配置的druidDatasourcesqlSessionFactoryBean.setDataSource(dataSource);//配置起別名sqlSessionFactoryBean.setTypeAliasesPackage("com.fs.pojo");return sqlSessionFactoryBean;}/*<!--配置MyBatis掃描dao的包,讓MyBatis動態(tài)代理生成這個dao的實(shí)現(xiàn)類,并交給ioc管理mybatis-spring這個包下MapperScannerConfigurer提供了spring于MyBatis的整合--><bean id="mapperScanner" class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <!-- 告訴MyBatis我dao在哪里.然后MyBatis將這個dao實(shí)現(xiàn),然后給spring管理--><property name="basePackage" value="com.fs.dao"/></bean>*///創(chuàng)建MyBatis動態(tài)代理掃描類@Beanpublic MapperScannerConfigurer getMapperScannerConfigurer(){//創(chuàng)建映掃描配置類MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();//設(shè)置動態(tài)代理掃描的dao的包mapperScannerConfigurer.setBasePackage("com.fs.dao");//交給spring管理return mapperScannerConfigurer;} }

TransactionManagerConfig

package com.fs.config;import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.jdbc.datasource.DataSourceTransactionManager; import org.springframework.transaction.PlatformTransactionManager;import javax.sql.DataSource;/* 聲明式事務(wù)配置類*/ public class TransactionManagerConfig {/*<!-- 將事務(wù)管理器交給ioc管理--><bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="dataSource"/></bean>*/@Beanpublic PlatformTransactionManager getTransactionManager(@Autowired DataSource dataSource){//使用Spring的平臺事務(wù)管理器,是一個接口,使用他的實(shí)現(xiàn)類構(gòu)造器傳遞一個連接池DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager();//傳遞一個連接池dataSourceTransactionManager.setDataSource(dataSource);return dataSourceTransactionManager;} }

實(shí)體類

Account

package com.fs.pojo;import lombok.Data;@Data public class Account {private Integer id;private String name;private Double money; }

Dao

AccountDao

package com.fs.dao;import com.fs.pojo.Account; import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Select; import org.apache.ibatis.annotations.Update;import java.util.List;public interface AccountDao {@Select("select * from account")List<Account> findAll();//查詢所有//根據(jù)名字修改money@Update("UPDATE account SET money = #{money} WHERE name = #{name}")void transferMoney(Account account);//根據(jù)名字查詢賬戶信息@Select("select * from account where name = #{name}")Account findAccountByName(@Param("name") String name); }

service

AccountService

package com.fs.service;import com.fs.pojo.Account; import org.springframework.transaction.annotation.Transactional;import java.util.List;/* 在接口上配置@Transactional,那么他下面的實(shí)現(xiàn)類都會進(jìn)行事務(wù)管理 這個注解就相當(dāng)于配置文件中的這些配置<tx:advice id="txAdvice" transaction-manager="transactionManager"><tx:attributes><tx:method name="*" read-only="false"/></tx:attributes></tx:advice><aop:config><aop:pointcut id="pt" expression="execution(* com.fs.service.impl.*.*(..))"/><aop:advisor advice-ref="txAdvice" pointcut-ref="pt"/></aop:config>如果不寫屬性,該注解的默認(rèn)配置為@Transactional(readOnly = false,timeout = -1,isolation = Isolation.DEFAULT,rollbackFor = {ArithmeticException.class, IOException.class},noRollbackFor = {},propagation = Propagation.REQUIRES_NEW)*/ public interface AccountService {List<Account> findAll();Account findAccountByName(String name);//對這個方法開啟事務(wù)使用默認(rèn)配置@Transactionalvoid transferMoneyAtoB(String aName,String bName,Integer money); }

AccountServiceImpl

package com.fs.service.impl;import com.fs.dao.AccountDao; import com.fs.pojo.Account; import com.fs.service.AccountService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service;import javax.sql.DataSource; import java.util.List;/*<!-- 把業(yè)務(wù)類 AccountServiceImpl 交給ioc管理 --><bean id="accountServiceImpl" class="com.fs.service.impl.AccountServiceImpl"> <!-- 依耐注入dao,這個dao被MyBatis動態(tài)代理實(shí)現(xiàn)后被spring存放在ioc容器中--><property name="accountDao" ref="accountDao"/></bean>*/ @Service public class AccountServiceImpl implements AccountService {//從ioc獲取MyBatis動態(tài)代理的accountDao實(shí)現(xiàn)類@Autowiredprivate AccountDao accountDao;@Autowiredprivate DataSource dataSource;@Overridepublic List<Account> findAll() {return accountDao.findAll();}@Overridepublic Account findAccountByName(String name) {return accountDao.findAccountByName(name);}//轉(zhuǎn)賬的業(yè)務(wù)實(shí)現(xiàn)@Overridepublic void transferMoneyAtoB(String aName, String bName, Integer money) {//先查出兩個人的數(shù)據(jù)Account aAccount = accountDao.findAccountByName(aName);Account bAccount = accountDao.findAccountByName(bName);//然后a減錢,b加錢aAccount.setMoney(aAccount.getMoney()-money);bAccount.setMoney(bAccount.getMoney()+money);//然后調(diào)用轉(zhuǎn)賬方法(sql語句為更新賬戶)accountDao.transferMoney(aAccount);//制作一個異常 // int i = 1/0;accountDao.transferMoney(bAccount);}}

測試類

package com.fs.service.impl;import com.fs.config.SpringConfig; import com.fs.pojo.Account; import com.fs.service.AccountService; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;import java.util.List;@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = SpringConfig.class) public class AccountServiceImplTest {@Autowiredprivate AccountService accountService;//測試查詢所有方法@Testpublic void findAll() {List<Account> all = accountService.findAll();System.out.println(all);}//測試轉(zhuǎn)賬方法已經(jīng)使用@Transactional綁定事務(wù)@Testpublic void transferMoneyAtoB() {//測試轉(zhuǎn)賬方法accountService.transferMoneyAtoB("小付","小花",100);}}

執(zhí)行效果

業(yè)務(wù)層轉(zhuǎn)賬方法正常運(yùn)行成功后數(shù)據(jù)表數(shù)據(jù)

由于我們測試代碼中是小付向小花轉(zhuǎn)賬100元,代碼執(zhí)行成功后應(yīng)該小付900,小花1100

業(yè)務(wù)層轉(zhuǎn)賬方法我們給制作一個異常1/0 的/ by zero異常,
運(yùn)存測試轉(zhuǎn)賬方法控制臺輸出

數(shù)據(jù)庫中表的數(shù)據(jù)
小付原本900,小花1100,我們進(jìn)行了轉(zhuǎn)賬業(yè)務(wù),但是制作了異常,事務(wù)會進(jìn)行回滾,所以金額不會發(fā)生變化

總結(jié)

以上是生活随笔為你收集整理的spring控制事务:声明式事务(注解)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。