一个spring中的事务管理练习:转账
dao层中的代码:
接口:IUserDao
import com.test.bean.User;
import java.util.List;
/**
* Created by Administrator on 2019/9/5.
*/
public interface IuserDao {
void save(User user);
void delete(int id);
void update(User user);
User get(int id);
List<User> select();
void updateMoneyOut(int transOutId, double m);
void updateMoneyIn(int transInId, double m);
}
实现类:UserDaoImpl
import com.test.bean.User;
import com.test.dao.IuserDao;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import javax.sql.DataSource;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
/**
* Created by Administrator on 2019/9/5.
*/
public class UserdaoImpl implements IuserDao {
private JdbcTemplate jdbcTemplate;
public void setDatasource(DataSource datasource) {
this.jdbcTemplate = new JdbcTemplate(datasource);
}
public void save(User user) {
this.jdbcTemplate.update("insert into account(name,money) values (?,?)",
user.getName(), user.getMoney());
}
public void delete(int id) {
this.jdbcTemplate.update("delete from account where id=?",id);
}
public void update(User user) {
this.jdbcTemplate.update("update account set name=?,money=? where id=?",
user.getName(),user.getMoney(),user.getId());
}
//查询单个对象
public User get(int id) {
User user = this.jdbcTemplate.queryForObject(
"select name,money from account where id=?",
new Object[]{id},
new RowMapper<User>() {
public User mapRow(ResultSet rs, int rowNum) throws SQLException {
User user = new User();
user.setName(rs.getString("name"));
user.setMoney(rs.getDouble("money"));
return user;
}
}
);
return user;
}
//查询一个集合
public List<User> select() {
List<User> list = this.jdbcTemplate.query(
"select name,money from account",
new RowMapper<User>() {
public User mapRow(ResultSet rs, int rowNum) throws SQLException {
User user = new User();
user.setName(rs.getString("name"));
user.setMoney(rs.getDouble("money"));
return user;
}
}
);
return list;
}
//转账的转出操作
public void updateMoneyOut(int transOutId, double m) {
this.jdbcTemplate.update(
"update account set money = money - ? where id=?",
m,transOutId);
}
//转账的转入操作
public void updateMoneyIn(int transInId, double m) {
this.jdbcTemplate.update(
"update account set money = money + ? where id=?",
m,transInId);
}
}
service层:
接口:IUserService
import com.test.bean.User;
import java.util.List;
/**
* Created by Administrator on 2019/9/5.
*/
public interface IUserService {
void save(User user);
void delete(int id);
void update(User user);
User get(int id);
List<User> select();
void trans(int transOutId,int transInId,double money);
}
实现类:UserServiceImpl
import com.test.bean.User;
import com.test.dao.IuserDao;
import com.test.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.List;
/**
* Created by Administrator on 2019/9/5.
*/
public class UserServiceImpl implements IUserService {
@Autowired
private IuserDao dao;
public void save(User user) {
dao.save(user);
}
public void delete(int id) {
dao.delete(id);
}
public void update(User user) {
dao.update(user);
}
public User get(int id) {
User user = dao.get(id);
return user;
}
public List<User> select() {
List<User> list = dao.select();
return list;
}
public void trans(int transOutId, int transInId, double money) {
dao.updateMoneyOut(transOutId,money);
//System.out.println(1/0);
dao.updateMoneyIn(transInId,money);
}
}
bean层
实体类:User
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
/**
* Created by Administrator on 2019/9/5.
*/
@Setter@Getter
public class User {
private String name;
private int id;
private double money;
@Override
public String toString() {
return "User["+name+","+money+"]";
}
}
下面是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: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/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
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<context:property-placeholder location="classpath:db.properties" system-properties-mode="NEVER"/>
<bean id="datasource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="${driverClassName}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</bean>
<bean id="dao" class="com.test.dao.impl.UserdaoImpl">
<property name="datasource" ref="datasource"/>
</bean>
<bean id="service" class="com.test.service.impl.UserServiceImpl"></bean>
<!--下面的配置是为service层加上事务-->
<!--配置事务管理器-->
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!--配置数据源-->
<property name="dataSource" ref="datasource"/>
</bean>
<!--配置事务-->
<aop:config>
<!--配置切入点-->
<aop:pointcut id="p1" expression="execution(* com.test.service.impl.UserServiceImpl.*(..))"/>
<!--配置切面-->
<aop:advisor advice-ref="tx" pointcut-ref="p1"/>
</aop:config>
<!--配置增强器-->
<tx:advice id="tx" transaction-manager="txManager">
<tx:attributes>
<tx:method name="select*" read-only="true"/>
<tx:method name="get*" read-only="true"/>
<tx:method name="*" read-only="false"/>
</tx:attributes>
</tx:advice>
</beans>
测试类:APP
import com.test.bean.User;
import com.test.service.IUserService;
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;
/**
* Created by Administrator on 2019/9/5.
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:application.xml")
public class APP {
@Autowired
private IUserService service;
@Test
public void testSave() {
User user = new User();
user.setName("jack");
user.setMoney(1234L);
service.save(user);
}
@Test
public void testDelete() {
service.delete(1);
}
@Test
public void testUpdate() {
User user = new User();
user.setId(4);
user.setName("rose");
user.setMoney(2345L);
service.update(user);
}
@Test
public void testGet() {
User user = service.get(4);
System.out.println(user);
}
@Test
public void testSelect() {
List<User> list = service.select();
System.out.println(list);
}
@Test
//测试转账操作
public void testTrans() {
service.trans(3,4,500);
}
}
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.offcn</groupId>
<artifactId>springo4</artifactId>
<version>1.0.0</version>
<properties>
<!--定义去全局变量
全局变量名:标签中的内容,例:project.spring.version
全局变量的值:标签之间的内容,例:5.0.2.RELEASE
下面的有的标签想要引用这个全局变量时,采用如下形式:
${全局变量名}
-->
<project.spring.version>5.0.2.RELEASE</project.spring.version>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!-- lombok依赖 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.20</version>
<scope>provided</scope>
</dependency>
<!--数据库依赖-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.38</version>
</dependency>
<!--德鲁伊连接池的依赖-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.10</version>
</dependency>
<!--使用spring框架的最基本的两个依赖-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${project.spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${project.spring.version}</version>
</dependency>
<!--spring的测试框架需要导入的依赖-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${project.spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
<version>${project.spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${project.spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${project.spring.version}</version>
</dependency>
<!--spring-jdbc需要导入的依赖-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${project.spring.version}</version>
</dependency>
<!--spring-tx需要导入的依赖,也是要使用springjdbc要导入的依赖-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${project.spring.version}</version>
</dependency>
<!--织入需要导入的包,即是用到了@Autowired的操作需要的依赖-->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.2</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.6</version>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
</resource>
<resource>
<directory>src/main/java</directory>
<filtering>true</filtering>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
</resource>
</resources>
</build>
</project>
结果:
3号给4号转500元之前:
转500元之后: