<dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.9.6</version> <scope>runtime</scope> </dependency> <dependency> <groupId>aopalliance</groupId> <artifactId>aopalliance</artifactId> <version>1.0</version> </dependency>
实体类Account.java
一、基于配置
applicationContext.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:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.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"> <!-- 注册bean --> <bean name="userDao" class="com.xiaobiti.dao.impl.UserDaoImpl"/> <bean name="xmlAdvice" class="com.xiaobiti.demo.xmlAdvice"/> <!-- 配置数据源 --> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <!-- 数据库驱动 --> <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/> <!-- 连接数据库url --> <property name="url" value="jdbc:mysql://localhost/spring?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai" /> <property name="username" value="root"/><!-- 连接数据库用户名 --> <property name="password" value="1234"/><!-- 连接数据库密码 --> </bean> <!-- 配置jdbc模板 --> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <!-- 默认必须使用数据源 --> <property name="dataSource" ref="dataSource"/> </bean> <!-- 注册bean --> <bean id="accountDao" class="com.xiaobiti.dao.impl.AccountDaoImpl"> <property name="jdbcTemplate" ref="jdbcTemplate"/> </bean> <!--开启自动代理支持--> <aop:aspectj-autoproxy/> <!-- 4.事务管理器,依赖于数据源 --> <bean id="transactionManager" class= "org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource" /></bean> <!-- 5.编写通知,需要编写对切入点和具体执行事务细节--> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes> <tx:method name="*" propagation="REQUIRED" isolation="DEFAULT" read-only="false" /></tx:attributes> </tx:advice> <!-- 6.编写aop,使用AspectJ的表达式,让spring自动对目标生成代理--> <aop:config> <aop:pointcut expression="execution(* com.itheima.*.*(..))" id="txPointCut" /> <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointCut"/> </aop:config> </beans>
AccountDao.java
package com.xiaobiti.dao; public interface AccountDao { public void transfer(String outUser,String inUser,Double money); }
AccountDaoImpl.java
package com.xiaobiti.dao.impl; import com.xiaobiti.dao.AccountDao; import org.springframework.jdbc.core.JdbcTemplate; public class AccountDaoImpl implements AccountDao { private JdbcTemplate jdbcTemplate; public void setJdbcTemplate(JdbcTemplate jdbcTemplate) { this.jdbcTemplate = jdbcTemplate; } // 转账 inUser:收款人; outUser:汇款人; money:收款金额 public void transfer(String outUser, String inUser, Double money) { // 收款时,收款用户的余额=现有余额+所汇金额 this.jdbcTemplate.update("update account set balance = balance + ? " + "where name = ?",money, inUser); // 模拟系统运行时的突发性问题 //int i = 1/0; // 汇款时,汇款用户的余额=现有余额-所汇金额 this.jdbcTemplate.update("update account set balance = balance - ?" + "where name = ?",money, outUser); } }
测试运行代码:
public static void main(String[] args) { ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml"); // 获取AccountDao实例 AccountDao accountDao = (AccountDao)applicationContext.getBean("accountDao"); // 调用实例中的转账方法 accountDao.transfer("李四", "张三", 100.0); // 输出提示信息 System.out.println("转账成功!"); }
二、基于注解
applicationContext.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:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.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"> <!-- 注册bean --> <bean name="userDao" class="com.xiaobiti.dao.impl.UserDaoImpl"/> <bean name="xmlAdvice" class="com.xiaobiti.demo.xmlAdvice"/> <!-- 配置数据源 --> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <!-- 数据库驱动 --> <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/> <!-- 连接数据库url --> <property name="url" value="jdbc:mysql://localhost/spring?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai" /> <property name="username" value="root"/><!-- 连接数据库用户名 --> <property name="password" value="1234"/><!-- 连接数据库密码 --> </bean> <!-- 配置jdbc模板 --> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <!-- 默认必须使用数据源 --> <property name="dataSource" ref="dataSource"/> </bean> <!-- 注册bean --> <bean id="accountDao" class="com.xiaobiti.dao.impl.AccountDaoImpl"> <property name="jdbcTemplate" ref="jdbcTemplate"/> </bean> <!--开启自动代理支持--> <aop:aspectj-autoproxy/> <!-- 4.事务管理器,依赖于数据源 --> <bean id="transactionManager" class= "org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource" /></bean> <!-- 5.编写通知,需要编写对切入点和具体执行事务细节--> <!-- 基于注解方式 --> <tx:annotation-driven transaction-manager="transactionManager"/> <!-- 6.编写aop,使用AspectJ的表达式,让spring自动对目标生成代理--> <aop:config> <aop:pointcut expression="execution(* com.itheima.*.*(..))" id="txPointCut" /> <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointCut"/> </aop:config> </beans>
AccountDao.java
package com.xiaobiti.dao; public interface AccountDao { public void transfer(String outUser,String inUser,Double money); }
AccountDaoImpl.java
package com.xiaobiti.dao.impl; import com.xiaobiti.dao.AccountDao; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.transaction.annotation.Isolation; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; public class AccountDaoImpl implements AccountDao { private JdbcTemplate jdbcTemplate; public void setJdbcTemplate(JdbcTemplate jdbcTemplate) { this.jdbcTemplate = jdbcTemplate; } // 转账 inUser:收款人; outUser:汇款人; money:收款金额 @Transactional(propagation = Propagation.REQUIRED,isolation = Isolation.DEFAULT,readOnly = false) public void transfer(String outUser, String inUser, Double money) { // 收款时,收款用户的余额=现有余额+所汇金额 this.jdbcTemplate.update("update account set balance = balance + ? " + "where name = ?",money, inUser); // 模拟系统运行时的突发性问题 //int i = 1/0; // 汇款时,汇款用户的余额=现有余额-所汇金额 this.jdbcTemplate.update("update account set balance = balance - ?" + "where name = ?",money, outUser); } }
测试运行代码:
public static void main(String[] args) { ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml"); // 获取AccountDao实例 AccountDao accountDao = (AccountDao)applicationContext.getBean("accountDao"); // 调用实例中的转账方法 accountDao.transfer("李四", "张三", 100.0); // 输出提示信息 System.out.println("转账成功!"); }