一、事务管理
1.1 JdbcTemplate
- 添加依赖
<?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.gupaoedu</groupId>
<artifactId>SpringJdbcTemplate</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>5.1.17.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.1.17.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<!-- 如果Mysql是8.0的就用这个驱动 -->
<!--<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.16</version>
</dependency>-->
<!-- 如果Mysql是5.7的就用这个驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.38</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.1</version>
</dependency>
</dependencies>
</project>
- 创建 User
package com.gupaoedu.pojo;
public class User {
private Integer id;
private String name;
private Integer age;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
'}';
}
}
- 新建 IUserDao
package com.gupaoedu.dao;
import com.gupaoedu.pojo.User;
import java.util.List;
public interface IUserDao {
public Integer addUser(User user);
public List<User> query();
}
- 新建 UserDaoImpl
package com.gupaoedu.dao.impl;
import com.gupaoedu.dao.IUserDao;
import com.gupaoedu.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Repository;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
@Repository
public class UserDaoImpl implements IUserDao {
@Autowired
private JdbcTemplate template;
private String sql;
public Integer addUser(User user) {
sql = "insert into users(name, age) values(?, ?)";
return template.update(sql, user.getName(), user.getAge());
}
public List<User> query() {
sql = "select * from users order by id desc";
List<User> users = template.query(sql, new RowMapper<User>() {
public User mapRow(ResultSet resultSet, int i) throws SQLException {
User user = new User();
try {
user.setId(resultSet.getInt("id"));
user.setName(resultSet.getString("name"));
user.setAge(resultSet.getInt("age"));
} catch (SQLException e) {
e.printStackTrace();
}
return user;
}
});
return users;
}
}
- 新建 IUserService
package com.gupaoedu.service;
import com.gupaoedu.pojo.User;
import java.util.List;
public interface IUserService {
public Integer addUser(User user);
public List<User> query();
}
- 新建 UserServiceImpl
package com.gupaoedu.service.impl;
import com.gupaoedu.dao.IUserDao;
import com.gupaoedu.pojo.User;
import com.gupaoedu.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class UserServiceImpl implements IUserService {
@Autowired
private IUserDao dao;
public Integer addUser(User user) {
return dao.addUser(user);
}
public List<User> query() {
return dao.query();
}
}
- 新建 JavaConfig
package com.gupaoedu;
import com.gupaoedu.pojo.User;
import com.gupaoedu.service.IUserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.*;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import javax.sql.DataSource;
@Configuration
@ComponentScan
public class JavaConfig {
@Bean
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost:3306/test?serverTimezone=UTC&useUnicode=true&characterEncoding=UTF-8");
dataSource.setUsername("root");
dataSource.setPassword("123456");
return dataSource;
}
@Bean
@DependsOn("dataSource")
public JdbcTemplate template(DataSource dataSource) {
return new JdbcTemplate(dataSource);
}
public static void main(String[] args) {
ApplicationContext ac = new AnnotationConfigApplicationContext(JavaConfig.class);
IUserService bean = ac.getBean(IUserService.class);
User user = new User();
user.setName("灰灰");
user.setAge(18);
System.out.println(bean.addUser(user));
System.out.println(bean.query());
}
}
- 执行结果
1
[User{id=1, name='灰灰', age=18}]
1.2 jdbc 事务管理机制
- 【IUserDao】新增 addUserInfo 和 transaction 接口;
package com.gupao.dao;
import com.gupao.pojo.User;
import java.util.List;
public interface IUserDao {
public Integer addUser(User user);
public List<User> query();
public Integer addUserInfo(String username, String password);
public Integer transaction(User user, String username, String password);
}
- 【UserDaoImpl】实现 addUserInfo 和 transaction 接口;
package com.gupao.dao.impl;
import com.gupao.dao.IUserDao;
import com.gupao.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Repository;
import java.sql.*;
import java.util.List;
@Repository
public class UserDaoImpl implements IUserDao {
private final String DRIVERNAME = "com.mysql.jdbc.Driver";
private final String URL = "jdbc:mysql://localhost:3306/test?serverTimezone=UTC&useUnicode=true&characterEncoding=UTF-8";
private final String USERNAME = "root";
private final String PASSWORD = "123456";
@Autowired
private JdbcTemplate template;
private String sql;
private Connection conn = null;
private PreparedStatement ps = null;
public Integer addUser(User user) {
/*sql = "insert into users(name, age) values(?, ?)";
int iRet = template.update(sql, user.getName(), user.getAge());*/
int iRet = 0;
try {
Class.forName(DRIVERNAME);
conn = DriverManager.getConnection(URL, USERNAME, PASSWORD);
sql = "insert into users(name, age) values(?, ?)";
ps = conn.prepareStatement(sql);
ps.setString(1, user.getName());
ps.setInt(2, user.getAge());
iRet = ps.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
} finally {
if(ps != null) {
try {
ps.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
return iRet;
}
public Integer addUserInfo(String userName, String passwrod) {
/*sql = "insert into user_info(username, password) values(?, ?)";
int iRet = template.update(sql, userName, passwrod);*/
int iRet = 0;
try {
Class.forName(DRIVERNAME);
conn = DriverManager.getConnection(URL, USERNAME, PASSWORD);
sql = "insert into user_info(username, password) values(?, ?)";
ps = conn.prepareStatement(sql);
ps.setString(1, userName);
ps.setString(2, passwrod);
iRet = ps.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
} finally {
if(ps != null) {
try {
ps.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
return iRet;
}
public Integer transaction(User user, String username, String password) {
int iRet = 0;
try {
Class.forName(DRIVERNAME);
conn = DriverManager.getConnection(URL, USERNAME, PASSWORD);
// 关闭自动提交
conn.setAutoCommit(false);
sql = "insert into users(name, age) values(?, ?)";
ps = conn.prepareStatement(sql);
ps.setString(1, user.getName());
ps.setInt(2, user.getAge());
iRet = ps.executeUpdate();
sql = "insert into user_info(username, password1) values(?, ?)";
ps = conn.prepareStatement(sql);
ps.setString(1, username);
ps.setString(2, password);
iRet += ps.executeUpdate();
conn.commit();
} catch (Exception e) {
try {
conn.rollback();
} catch (SQLException e1) {
e1.printStackTrace();
}
e.printStackTrace();
} finally {
if(ps != null) {
try {
ps.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
return iRet;
}
public List<User> query() {
sql = "select * from users order by id desc";
List<User> list = template.query(sql, new RowMapper<User>() {
public User mapRow(ResultSet resultSet, int i) throws SQLException {
User user = new User();
try {
user.setId(resultSet.getInt("id"));
user.setName(resultSet.getString("name"));
user.setAge(resultSet.getInt("age"));
} catch (SQLException e) {
e.printStackTrace();
}
return user;
}
});
return list;
}
}
- 【IUserService】新增 addUserInfo 和 transaction 接口;
package com.gupao.service;
import com.gupao.pojo.User;
import java.util.List;
public interface IUserService {
public Integer addUser(User user);
public List<User> query();
public Integer addUserInfo(String username, String password);
public Integer transaction(User user, String username, String password);
}
- 【UserServiceImpl】新增 addUserInfo 和 transaction;
package com.gupao.service.impl;
import com.gupao.dao.IUserDao;
import com.gupao.pojo.User;
import com.gupao.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class UserServicImpl implements IUserService {
@Autowired
private IUserDao userDao;
public Integer addUser(User user) {
return userDao.addUser(user);
}
public List<User> query() {
return userDao.query();
}
public Integer addUserInfo(String username, String password) {
return userDao.addUserInfo(username, password);
}
public Integer transaction(User user, String username, String password) {
return userDao.transaction(user, username, password);
}
}
- 修改 JavaConfig
package com.gupao;
import com.gupao.pojo.User;
import com.gupao.service.IUserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.*;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import javax.sql.DataSource;
@Configuration
@ComponentScan
public class JavaConfig {
@Bean
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost:3306/test?serverTimezone=UTC&useUnicode=true&characterEncoding=UTF-8");
dataSource.setUsername("root");
dataSource.setPassword("123456");
return dataSource;
}
@Bean
@DependsOn("dataSource")
public JdbcTemplate template(DataSource dataSource) {
return new JdbcTemplate(dataSource);
}
public static void main(String[] args) {
ApplicationContext ac = new AnnotationConfigApplicationContext(JavaConfig.class);
IUserService bean = ac.getBean(IUserService.class);
User user = new User();
user.setName("灰灰");
user.setAge(18);
/*System.out.println(bean.addUser(user));
System.out.println(bean.addUserInfo("huihui", "123456"));*/
System.out.println(bean.transaction(user, "huihui", "123456"));
}
}
1.3 jdk 代理机制实现事务管理
- 新建【DbUtils】
package com.gupao.utils;
import java.sql.Connection;
import java.sql.DriverManager;
public class DbUtils {
private static final String DRIVERNAME = "com.mysql.jdbc.Driver";
private static final String URL = "jdbc:mysql://localhost:3306/test?serverTimezone=UTC&useUnicode=true&characterEncoding=UTF-8";
private static final String USERNAME = "root";
private static final String PASSWORD = "123456";
private static Connection conn = null;
public static Connection getConnection() {
if(conn == null) {
try {
Class.forName(DRIVERNAME);
conn = DriverManager.getConnection(URL, USERNAME, PASSWORD);
} catch (Exception e) {
e.printStackTrace();
}
}
return conn;
}
}
- 修改【UserDaoImpl】
package com.gupao.dao.impl;
import com.gupao.dao.IUserDao;
import com.gupao.pojo.User;
import com.gupao.utils.DbUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Repository;
import java.sql.*;
import java.util.List;
@Repository
public class UserDaoImpl implements IUserDao {
private final String DRIVERNAME = "com.mysql.jdbc.Driver";
private final String URL = "jdbc:mysql://localhost:3306/test?serverTimezone=UTC&useUnicode=true&characterEncoding=UTF-8";
private final String USERNAME = "root";
private final String PASSWORD = "123456";
@Autowired
private JdbcTemplate template;
private String sql;
private Connection conn = null;
private PreparedStatement ps = null;
public Integer addUser(User user) throws SQLException {
/*sql = "insert into users(name, age) values(?, ?)";
int iRet = template.update(sql, user.getName(), user.getAge());*/
int iRet = 0;
conn = DbUtils.getConnection();
sql = "insert into users(name, age) values(?, ?)";
ps = conn.prepareStatement(sql);
ps.setString(1, user.getName());
ps.setInt(2, user.getAge());
iRet = ps.executeUpdate();
return iRet;
}
public Integer addUserInfo(String userName, String passwrod) throws Exception {
/*sql = "insert into user_info(username, password) values(?, ?)";
int iRet = template.update(sql, userName, passwrod);*/
int iRet = 0;
conn = DbUtils.getConnection();
sql = "insert into user_info(username, password) values(?, ?)";
ps = conn.prepareStatement(sql);
ps.setString(1, userName);
ps.setString(2, passwrod);
iRet = ps.executeUpdate();
return iRet;
}
public Integer transaction(User user, String username, String password) throws Exception {
int iRet = 0;
conn = DbUtils.getConnection();
sql = "insert into users(name, age) values(?, ?)";
ps = conn.prepareStatement(sql);
ps.setString(1, user.getName());
ps.setInt(2, user.getAge());
iRet = ps.executeUpdate();
sql = "insert into user_info(username, password) values(?, ?)";
ps = conn.prepareStatement(sql);
ps.setString(1, username);
ps.setString(2, password);
iRet += ps.executeUpdate();
return iRet;
}
public List<User> query() {
sql = "select * from users order by id desc";
List<User> list = template.query(sql, new RowMapper<User>() {
public User mapRow(ResultSet resultSet, int i) throws SQLException {
User user = new User();
try {
user.setId(resultSet.getInt("id"));
user.setName(resultSet.getString("name"));
user.setAge(resultSet.getInt("age"));
} catch (SQLException e) {
e.printStackTrace();
}
return user;
}
});
return list;
}
}
- 修改【IUserDao】
package com.gupao.dao;
import com.gupao.pojo.User;
import java.sql.SQLException;
import java.util.List;
public interface IUserDao {
public Integer addUser(User user) throws SQLException;
public List<User> query();
public Integer addUserInfo(String username, String password) throws Exception;
public Integer transaction(User user, String username, String password) throws Exception;
}
- 修改【UserServicImpl】
package com.gupao.service.impl;
import com.gupao.dao.IUserDao;
import com.gupao.dao.impl.UserDaoImpl;
import com.gupao.pojo.User;
import com.gupao.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class UserServicImpl implements IUserService {
//@Autowired
private IUserDao userDao = new UserDaoImpl();
public Integer addUser(User user) throws Exception {
return userDao.addUser(user);
}
public List<User> query() {
return userDao.query();
}
public Integer addUserInfo(String username, String password) throws Exception {
return userDao.addUserInfo(username, password);
}
public Integer transaction(User user, String username, String password) throws Exception {
//return userDao.tx(user, username, password);
int iRet = 0;
iRet = userDao.addUser(user);
iRet += userDao.addUserInfo(username, password);
return iRet;
}
}
- 修改【IUserService】
package com.gupao.service;
import com.gupao.pojo.User;
import java.util.List;
public interface IUserService {
public Integer addUser(User user) throws Exception;
public List<User> query();
public Integer addUserInfo(String username, String password) throws Exception;
public Integer transaction(User user, String username, String password) throws Exception;
}
- 修改【JavaConfig】
package com.gupao;
import com.gupao.pojo.User;
import com.gupao.service.IUserService;
import com.gupao.service.impl.UserServicImpl;
import com.gupao.utils.DbUtils;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.*;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import javax.sql.DataSource;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.sql.Connection;
@Configuration
@ComponentScan
public class JavaConfig {
@Bean
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost:3306/test?serverTimezone=UTC&useUnicode=true&characterEncoding=UTF-8");
dataSource.setUsername("root");
dataSource.setPassword("123456");
return dataSource;
}
@Bean
@DependsOn("dataSource")
public JdbcTemplate template(DataSource dataSource) {
return new JdbcTemplate(dataSource);
}
public static void main(String[] args) {
/*ApplicationContext ac = new AnnotationConfigApplicationContext(JavaConfig.class);
IUserService bean = ac.getBean(IUserService.class);
User user = new User();
user.setName("灰灰");
user.setAge(18);
*//*System.out.println(bean.addUser(user));
System.out.println(bean.addUserInfo("huihui", "123456"));*//*
System.out.println(bean.tx(user, "huihui", "123456"));*/
// 获取目标对象
final IUserService target = new UserServicImpl();
// 获取代理对象
IUserService proxy = (IUserService) Proxy.newProxyInstance(JavaConfig.class.getClassLoader(), target.getClass().getInterfaces(), new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Connection conn = null;
try {
conn = DbUtils.getConnection();
conn.setAutoCommit(false);
method.invoke(target, args[0], args[1], args[2]);// 目标对象执行
System.out.println("执行成功 ... ... ");
conn.commit();
} catch (Exception e) {
e.printStackTrace();
System.out.println("执行失败,数据回滚 ... ");
conn.rollback();
} finally {
conn.close();
}
return null;
}
});
User user = new User();
user.setName("灰灰");
user.setAge(18);
try {
proxy.transaction(user, "huihui", "123456");
} catch (Exception e) {
e.printStackTrace();
}
}
}
1.4 基于 Aspect J 的方式自定义事务
- 定义自定义注解
package com.gupao.annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface GpTx {
}
- 在【UserServicImpl】的【transaction】方法上添加【@GpTx】注解
package com.gupao.service.impl;
import com.gupao.annotation.GpTx;
import com.gupao.dao.IUserDao;
import com.gupao.dao.impl.UserDaoImpl;
import com.gupao.pojo.User;
import com.gupao.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class UserServicImpl implements IUserService {
//@Autowired
private IUserDao userDao = new UserDaoImpl();
public Integer addUser(User user) throws Exception {
return userDao.addUser(user);
}
public List<User> query() {
return userDao.query();
}
public Integer addUserInfo(String username, String password) throws Exception {
return userDao.addUserInfo(username, password);
}
@GpTx
public Integer transaction(User user, String username, String password) throws Exception {
//return userDao.tx(user, username, password);
int iRet = 0;
iRet = userDao.addUser(user);
iRet += userDao.addUserInfo(username, password);
return iRet;
}
}
- 自定义切面类【GpAspect】
package com.gupao.aspect;
import com.gupao.utils.DbUtils;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
import java.sql.Connection;
import java.sql.SQLException;
@Aspect
@Component
public class GpAspect {
/**
* 事务处理的前置方法
* @throws SQLException
*/
@Before(value = "@annotation(com.gupao.annotation.GpTx)")
public void beforeTx() throws SQLException {
Connection conn = DbUtils.getConnection();
conn.setAutoCommit(false);
}
/**
* 事务处理的后置通知
* @throws SQLException
*/
@AfterReturning(value = "@annotation(com.gupao.annotation.GpTx)")
public void afterReturningTx() throws SQLException {
Connection conn = DbUtils.getConnection();
System.out.println("执行成功 ... ... ");
conn.commit();
}
/**
* 事务处理的最终通知
* @throws SQLException
*/
@After(value = "@annotation(com.gupao.annotation.GpTx)")
public void afterTx() throws SQLException {
Connection conn = DbUtils.getConnection();
//conn.close();
}
@AfterThrowing(value = "@annotation(com.gupao.annotation.GpTx)")
public void afterThrowingTx() throws SQLException {
Connection conn = DbUtils.getConnection();
System.out.println("失败回滚 ... ... ");
conn.rollback();
}
}
- 【JavaConfig】添加【@EnableAspectJAutoProxy】类注解
package com.gupao;
import com.gupao.pojo.User;
import com.gupao.service.IUserService;
import com.gupao.service.impl.UserServicImpl;
import com.gupao.utils.DbUtils;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.*;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import javax.sql.DataSource;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.sql.Connection;
@Configuration
@ComponentScan
@EnableAspectJAutoProxy
public class JavaConfig {
@Bean
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost:3306/test?serverTimezone=UTC&useUnicode=true&characterEncoding=UTF-8");
dataSource.setUsername("root");
dataSource.setPassword("123456");
return dataSource;
}
@Bean
@DependsOn("dataSource")
public JdbcTemplate template(DataSource dataSource) {
return new JdbcTemplate(dataSource);
}
public static void main(String[] args) {
/*ApplicationContext ac = new AnnotationConfigApplicationContext(JavaConfig.class);
IUserService bean = ac.getBean(IUserService.class);
User user = new User();
user.setName("灰灰");
user.setAge(18);
*//*System.out.println(bean.addUser(user));
System.out.println(bean.addUserInfo("huihui", "123456"));*//*
System.out.println(bean.tx(user, "huihui", "123456"));*/
// 获取目标对象
final IUserService target = new UserServicImpl();
// 获取代理对象
IUserService proxy = (IUserService) Proxy.newProxyInstance(JavaConfig.class.getClassLoader(), target.getClass().getInterfaces(), new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Connection conn = null;
try {
conn = DbUtils.getConnection();
conn.setAutoCommit(false);
method.invoke(target, args[0], args[1], args[2]);// 目标对象执行
System.out.println("执行成功 ... ... ");
conn.commit();
} catch (Exception e) {
e.printStackTrace();
System.out.println("执行失败,数据回滚 ... ");
conn.rollback();
} finally {
conn.close();
}
return null;
}
});
User user = new User();
user.setName("灰灰");
user.setAge(18);
try {
proxy.transaction(user, "huihui", "123456");
} catch (Exception e) {
e.printStackTrace();
}
}
}
- 添加【JavaConfigMain】
package com.gupao;
import com.gupao.pojo.User;
import com.gupao.service.IUserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class JavaConfigMain {
public static void main(String[] args) throws Exception {
ApplicationContext ac = new AnnotationConfigApplicationContext(JavaConfig.class);
IUserService bean = ac.getBean(IUserService.class);
User user = new User();
user.setName("令狐");
user.setAge(18);
bean.transaction(user, "linghu", "123456");
}
}
1.5 Spring 中的事务实现
- 新建 Maven 工程,添加依赖
<dependencies>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>5.1.17.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.1.17.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<!-- 如果Mysql是8.0的就用这个驱动 -->
<!--<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.16</version>
</dependency>-->
<!-- 如果Mysql是5.7的就用这个驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.38</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-logging/commons-logging -->
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/log4j/log4j -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<!-- https://mvnrepository.com/artifact/logkit/logkit -->
<dependency>
<groupId>logkit</groupId>
<artifactId>logkit</artifactId>
<version>1.0.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/avalon-framework/avalon-framework -->
<dependency>
<groupId>avalon-framework</groupId>
<artifactId>avalon-framework</artifactId>
<version>4.1.5</version>
</dependency>
</dependencies>
- 新建【User】
package com.gupao.pojo;
public class User {
private Integer id;
private String userName;
private Integer age;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public User(Integer id, String userName, Integer age) {
this.id = id;
this.userName = userName;
this.age = age;
}
public User(String userName, Integer age) {
this.userName = userName;
this.age = age;
}
}
- 新建【IUserDao】
package com.gupao.dao;
import com.gupao.pojo.User;
public interface IUserDao {
public Integer addUser(User user) throws Exception;
public Integer updateUser(User user) throws Exception;
}
- 新建【UserDaoImpl】
package com.gupao.dao.impl;
import com.gupao.dao.IUserDao;
import com.gupao.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;
@Repository
public class UserDaoImpl implements IUserDao {
@Autowired
private JdbcTemplate template;
private String sql;
public Integer addUser(User user) throws Exception {
sql = "insert into users(name, age) values(?, ?)";
return template.update(sql, user.getUserName(), user.getAge());
}
public Integer updateUser(User user) throws Exception {
sql = "update users set name=?, age=? where id=?";
return template.update(sql, user.getUserName(), user.getAge(), user.getId());
}
}
- 新建【IUserService】
package com.gupao.service;
import com.gupao.pojo.User;
public interface IUserService {
public Integer addUser(User user) throws Exception;
public Integer updateUser(User user) throws Exception;
public void transaction() throws Exception;
}
- 新建【UserServiceImpl】
package com.gupao.service.impl;
import com.gupao.dao.IUserDao;
import com.gupao.pojo.User;
import com.gupao.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class UserServiceImpl implements IUserService {
@Autowired
private IUserDao dao;
public Integer addUser(User user) throws Exception {
return dao.addUser(user);
}
public Integer updateUser(User user) throws Exception {
return dao.updateUser(user);
}
public void transaction() throws Exception {
User user = new User("清扬", 18);
addUser(user);
user.setId(1);
user.setUserName("零一");
updateUser(user);
}
}
- 【Resource】下新建【db.properties】
jdbc_driver=com.mysql.jdbc.Driver
jdbc_url=jdbc:mysql://localhost:3306/test?serverTimezone=UTC&useUnicode=true&characterEncoding=UTF-8
jdbc_username=root
jdbc_password=123456
- 【Resource】下新建【applicationContext.xml】
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
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-4.3.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.1.xsd">
<context:component-scan base-package="com.gupao.*" />
<!-- 加载数据配置文件 -->
<context:property-placeholder location="db.properties" />
<!-- 配置数据源 -->
<bean class="org.springframework.jdbc.datasource.DriverManagerDataSource" id="dataSource">
<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>
<!-- 配置JdcbTemplate -->
<bean class="org.springframework.jdbc.core.JdbcTemplate">
<constructor-arg name="dataSource" ref="dataSource" />
</bean>
</beans>
- 新建【JavaConfig】
package com.gupao;
import com.gupao.service.IUserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class JavaConfig {
public static void main(String[] args) throws Exception {
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
IUserService bean = ac.getBean(IUserService.class);
bean.transaction();
}
}
1.5.1 基于 xml 文件
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
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-4.3.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.1.xsd">
<context:component-scan base-package="com.gupao.*" />
<!-- 加载数据配置文件 -->
<context:property-placeholder location="db.properties" />
<!-- 配置数据源 -->
<bean class="org.springframework.jdbc.datasource.DriverManagerDataSource" id="dataSource">
<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>
<!-- 配置JdcbTemplate -->
<bean class="org.springframework.jdbc.core.JdbcTemplate">
<constructor-arg name="dataSource" ref="dataSource" />
</bean>
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<tx:advice id="txAdvice" transaction-manager="txManager">
<!-- the transactional semantics... -->
<tx:attributes>
<!-- all methods starting with 'get' are read-only -->
<tx:method name="tran*" propagation="REQUIRED" isolation="DEFAULT"/>
<!-- other methods use the default transaction settings (see below) -->
<tx:method name="*"/>
</tx:attributes>
</tx:advice>
<aop:config>
<aop:pointcut id="tx" expression="execution(* com.gupao.service..*.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="tx"/>
</aop:config>
</beans>
1.5.2 基于注解
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
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-4.3.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.1.xsd">
<context:component-scan base-package="com.gupao.*" />
<!-- 加载数据配置文件 -->
<context:property-placeholder location="db.properties" />
<!-- 配置数据源 -->
<bean class="org.springframework.jdbc.datasource.DriverManagerDataSource" id="dataSource">
<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>
<!-- 配置JdcbTemplate -->
<bean class="org.springframework.jdbc.core.JdbcTemplate">
<constructor-arg name="dataSource" ref="dataSource" />
</bean>
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- 开启事务的注解支持 -->
<tx:annotation-driven transaction-manager="txManager" />
</beans>
- 添加【@Transactional】注解
package com.gupao.service.impl;
import com.gupao.dao.IUserDao;
import com.gupao.pojo.User;
import com.gupao.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
public class UserServiceImpl implements IUserService {
@Autowired
private IUserDao dao;
public Integer addUser(User user) throws Exception {
return dao.addUser(user);
}
public Integer updateUser(User user) throws Exception {
return dao.updateUser(user);
}
@Transactional
public void transaction() throws Exception {
User user = new User("清扬", 18);
addUser(user);
user.setId(1);
user.setUserName("零一");
updateUser(user);
}
}