运行一下代码的时候需要注意的问题!
注意:确保,自己创建的数据表的类型支持事物。 支持事物的数据表的类型为:BDB 和 InnoDB。
第二:注意代码的规范,避免出现不必要的错误!本人深有感触!
文章源码链接:https://download.csdn.net/download/weixin_45634682/15466241
备注:资源免费,但是需要关注我之后,才能下载!
1.先创建 dao层和service层,先将项目搭建起来!
UserDao接口
package com.dl.code.dao;
/**
* Created with IntelliJ IDEA.
* 作者: 代蒙恩
* 日期: 2021/2/25
* 时间: 15:59
* 描述: spring事物学习
* 内容:
*/
public interface UserDao {
//入账操作
public void increase(Integer id,Double money);
//转账操作
public void decrease(Integer id,Double money);
}
UserDaoImpl实现类
package com.dl.code.dao.impl;
import com.dl.code.dao.UserDao;
import org.springframework.jdbc.core.JdbcTemplate;
/**
* Created with IntelliJ IDEA.
* 作者: 代蒙恩
* 日期: 2021/2/25
* 时间: 15:59
* 描述: spring事物学习
* 内容:
*/
public class UserDaoImpl implements UserDao {
private JdbcTemplate jdbcTemplate;
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
@Override
public void increase(Integer id, Double money) {
//执行sql语句
int update = jdbcTemplate.update("update `user` set money = money + ? where id = ?", money, id);
}
@Override
public void decrease(Integer id, Double money) {
int update = jdbcTemplate.update("update `user` set money = money - ? where id = ?", money, id);
}
}
UserService接口
package com.dl.code.service;
/**
* Created with IntelliJ IDEA.
* 作者: 代蒙恩
* 日期: 2021/2/25
* 时间: 16:00
* 描述: spring事物学习
* 内容:
*/
public interface UserService {
//从 某人 向 某人 转账
public void transfer(Integer from,Integer to,Double money);
}
UserServiceImpl实现类
package com.dl.code.service.impl;
import com.dl.code.dao.UserDao;
import com.dl.code.service.UserService;
/**
* Created with IntelliJ IDEA.
* 作者: 代蒙恩
* 日期: 2021/2/25
* 时间: 16:00
* 描述: spring事物学习
* 内容:
*/
public class UserServiceImpl implements UserService {
private UserDao userDao;
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
@Override
public void transfer(Integer from, Integer to, Double money) {
//转账
userDao.decrease(from,money);
//模拟异常
// 这里可以先注释掉之后运行程序,观看数据库中的变化,
// 然后在恢复,再次运行程序,再次观看数据库中的变化
int i = 1 / 0;
//入账
userDao.increase(to,money);
}
}
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:context="http://www.springframework.org/schema/context"
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/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- 配置数据源 -->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="username" value="root"/>
<property name="password" value=""/>
<property name="url" value="jdbc:mysql:///java2010"/>
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
</bean>
<!-- 配置平台事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- 配置JdbcTemplate对象 -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- 配置事务通知 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<!--
相关的属性介绍
isolation : 用于指定事务的隔离级别。默认值是DEFAULT,表示使用数据库的默认隔离级别。
propagation : 用于指定事务的传播行为。默认值是REQUIRED,表示一定会有事务,
如果方法是增删改的时候,可以选择这个默认值。
如果是查询的方法的时候,可以选择SUPPORTS。
read-only : 用于指定事务是否是只读,只有查询方法的时候设置成true。默认值是false,表示可读可写。
timeout : 用于指定事务的超时时间,默认值是-1,表示永不超时。如果指定了数值,其单位是以秒为单位的。即 20 就是20秒。
rollback-for : 用于指定一个异常,当产生改异常的时候,事务会进行回滚,产生其他异常,事务不会进行回滚。
没有默认值,如果不写,则表示无论产生任何异常事务都不会进行回滚。
no-rollback-for : 用于指定一个异常,表示当产生该异常的时候,事务不进行回滚,产生其他异常的时候,事务会进行回滚。
没有默认值,如果不写,表示任何异常都会进行回滚。
-->
<tx:attributes>
<tx:method name="transfer" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false"/>
<!-- 注意:这里面可以写多个 tx:method 本次测试,只有一个方法,所在这里只写了一个 -->
</tx:attributes>
</tx:advice>
<!-- 配置切面 -->
<aop:config>
<aop:pointcut id="txPC" expression="execution(* com.dl.code.service.impl.UserServiceImpl.transfer(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="txPC"/>
</aop:config>
<!-- 创建UserDaoImpl对象 -->
<bean id="userDao" class="com.dl.code.dao.impl.UserDaoImpl">
<property name="jdbcTemplate" ref="jdbcTemplate"/>
</bean>
<!-- 创建UserServiceImpl对象 -->
<bean id="userService" class="com.dl.code.service.impl.UserServiceImpl">
<property name="userDao" ref="userDao"/>
</bean>
</beans>
测试代码部分
@Test
public void test1(){
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
// JdbcTemplate jdbcTemplate = (JdbcTemplate) applicationContext.getBean("jdbcTemplate");
UserService userService = (UserService) applicationContext.getBean("userService");
//从ID = 1 的用户 向 ID = 2的用户 转账 100元
userService.transfer(1,2,100d);
}