通过AOP控制事务的案例
生活随笔
收集整理的這篇文章主要介紹了
通过AOP控制事务的案例
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
1.xml配置版
執行以下sql語句
create table account(id int primary key auto_increment,name varchar(40),money float )character set utf8 collate utf8_general_ci; ? insert into account(name,money) values('aaa',1000); insert into account(name,money) values('bbb',1000);創建對應的實體類
Account.java
public class Account {private int id;private String name;private double money;}AccountDao.java
public interface AccountDao {void saveAccount(Account account); ?Account queryByName(String sourceName);void update(Account account); }AccountDaoImpl.java
@Repository("accountDao") public class AccountDaoImpl implements AccountDao { ?@Autowiredprivate QueryRunner queryRunner; ?@Autowiredprivate ConnectionUtils connectionUtils; ?@Overridepublic void saveAccount(Account account) {String sql = "insert into account(name,money) values(?,?) ";try {queryRunner.update(connectionUtils.getConnection(),sql, account.getName(), account.getMoney());} catch (SQLException e) {e.printStackTrace();}}@Overridepublic Account queryByName(String sourceName) {String sql = "select * from account where name=? ";List<Account> accounts = null;try {accounts = queryRunner.query(connectionUtils.getConnection(),sql, new BeanListHandler<Account>(Account.class),sourceName);if (accounts.isEmpty()) {return null;}if (accounts.size() > 1) {throw new RuntimeException("結果集不唯一");}return accounts.get(0);} catch (SQLException e) {throw new RuntimeException(e);}}@Overridepublic void update(Account account) {String sql = "update account set name=?,money=? where id=? ";try {queryRunner.update(connectionUtils.getConnection(),sql, account.getName(), account.getMoney(), account.getId());} catch (SQLException e) {e.printStackTrace();}}}AccountService.java
public interface AccountService { ?/*** 轉賬* @param sourceName ? ? ? 轉出賬戶名稱* @param targetName ? ? ? 轉入賬戶名稱* @param money ? ? ? ? ? ? 轉賬金額*/void transfer(String sourceName,String targetName,Float money); } AccountServiceImpl.java@Service("accountService") public class AccountServiceImpl implements AccountService { ?@Autowiredprivate AccountDao accountDao; ?@Autowiredprivate TransactionManager transactionManager; ?@Overridepublic void transfer(String sourceName, String targetName, Float money) {//查詢出原金額Account source = accountDao.queryByName(sourceName);Account target = accountDao.queryByName(targetName);//更新金額source.setMoney(source.getMoney() - money);target.setMoney(target.getMoney() + money);//提交數據accountDao.update(source);//模擬異常int a=1/0;accountDao.update(target);} }ConnectionUtils.java
/*** 連接的工具類,用于綁定連接到ThreadLocal上*/ @Component public class ConnectionUtils { ?private ThreadLocal<Connection> tl = new ThreadLocal<>(); ?@Autowiredprivate DataSource dataSource; ? ?/*** 從當前線程獲取連接* @return*/public Connection getConnection(){try{//1.獲取當前線程的連接Connection conn = tl.get();//2.判斷當前線程上有沒有if(conn == null){//3.從數據源中獲取一個conn = dataSource.getConnection();//4.綁定到當前線程上tl.set(conn);}//5.返回線程上的連接return tl.get();}catch (Exception e){throw new RuntimeException(e);}} ?/*** 線程和連接的解綁*/public void remove(){tl.remove();} }TransactionManager.java
/*** 事務管理器*/ @Component public class TransactionManager { ?@Autowiredprivate ConnectionUtils connectionUtils; ? ?//開啟事務public void beginTransaction(){try {connectionUtils.getConnection().setAutoCommit(false);}catch (Exception e){e.printStackTrace();}} ?//提交事務public void commit(){try {connectionUtils.getConnection().commit();}catch (Exception e){e.printStackTrace();}} ?//回滾事務public void rollback(){try {connectionUtils.getConnection().rollback();}catch (Exception e){e.printStackTrace();}} ? ?//釋放資源public void close(){try {connectionUtils.getConnection().close();connectionUtils.remove();//解綁}catch (Exception e){e.printStackTrace();}} }beans.xml
<?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/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> ?<context:component-scan base-package="com.itheima"></context:component-scan> ?<!-- 引入數據庫的配置文件 --><context:property-placeholder location="druid.properties"/><!-- 數據庫連接池配置 --><bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"><property name="driverClassName" value="${driverClassName}"></property><property name="url" value="${url}"></property><property name="username" value="${username}"></property><property name="password" value="${password}"></property></bean> ?<!-- 配置QueryRunner--><bean id="queryRunner" class="org.apache.commons.dbutils.QueryRunner"></bean> ?<bean id="logger" class="com.itheima.utils.TransactionManager"></bean> ? ?<aop:config><aop:pointcut expression="execution(* com.itheima.service.impl.*.*(..))" id="pt1"/> ?<aop:aspect id="logAdvice" ref="logger"><aop:before method="beginTransaction" pointcut-ref="pt1"/><aop:after-throwing method="rollback" pointcut-ref="pt1"/><aop:after-returning method="commit" pointcut-ref="pt1"/><aop:after method="close" pointcut-ref="pt1"/></aop:aspect></aop:config> ? </beans>druid.properties
driverClassName=com.mysql.jdbc.Driver url=jdbc:mysql://127.0.0.1:3306/spring_day01 username=root password=123456accountTest.java
public class AccountTest {AccountService accountService=null;@Beforepublic void beforeMethod(){ApplicationContext applicationContext=new ClassPathXmlApplicationContext("bean.xml");accountService = (AccountService) applicationContext.getBean("accountService");} ?@Testpublic void testTransfer(){accountService.transfer("aaa","bbb",100f);} }2.注解版
TransactionManager.java
/*** 事務管理器*/ @Component @Aspect ?//表示當前類是一個切面類 public class TransactionManager { ?@Autowiredprivate ConnectionUtils connectionUtils; ?@Pointcut("execution(* com.itheima.service.impl.*.*(..))")private void pointcutExcution() {} ?/*** 環繞通知* @param joinPoint* @return*/@Around("pointcutExcution()")public Object aroundMethod(ProceedingJoinPoint joinPoint) {Object result = null;try {beginTransaction();Object[] args = joinPoint.getArgs();result = joinPoint.proceed(args);commit();} catch (Throwable e) {e.printStackTrace();rollback();} finally {close();}return result;} ?//開啟事務public void beginTransaction() {try {connectionUtils.getConnection().setAutoCommit(false);} catch (Exception e) {e.printStackTrace();}} ?//提交事務public void commit() {try {connectionUtils.getConnection().commit();} catch (Exception e) {e.printStackTrace();}} ?//回滾事務public void rollback() {try {connectionUtils.getConnection().rollback();} catch (Exception e) {e.printStackTrace();}} ?//釋放資源public void close() {try {connectionUtils.getConnection().close();connectionUtils.remove();//解綁} catch (Exception e) {e.printStackTrace();}} }beans.xml
<!-- 開啟Spring對注解aop的支持--> <aop:aspectj-autoproxy></aop:aspectj-autoproxy>?
總結
以上是生活随笔為你收集整理的通过AOP控制事务的案例的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Jquery插件入门之Validate插
- 下一篇: CountDownLatch闭锁