1.配置pom.xml
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.36</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.2</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.3.2</version>
</dependency>
<dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.1.2</version>
</dependency>
<dependency>
<groupId>commons-dbutils</groupId>
<artifactId>commons-dbutils</artifactId>
<version>1.7</version>
</dependency>
</dependencies>
2.配置事务和连接
连接
public class ConnectionUtils {
private ThreadLocal<Connection> tl =new ThreadLocal<>();
private DataSource dataSource;
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}
/**
* 获取当前线程的连接
*/
public Connection getThreadConnection(){
//从threadLocal获取
Connection conn = tl.get();
try {
//判断线程有连接
if (conn==null){
conn =dataSource.getConnection();
tl.set(conn);
}
} catch (SQLException e) {
e.printStackTrace();
}
return conn;
}
public void removeConnection(){
tl.remove();
}
}
事务
public class TransactionManager {
private ConnectionUtils connectionUtils;
public void setConnectionUtils(ConnectionUtils connectionUtils) {
this.connectionUtils = connectionUtils;
}
/**
* 开启事务
*/
public void beginTransaction(){
try {
connectionUtils.getThreadConnection().setAutoCommit(false);
} catch (SQLException e) {
e.printStackTrace();
}
}
/**
* 提交
*/
public void commit(){
try {
connectionUtils.getThreadConnection().commit();
} catch (SQLException e) {
e.printStackTrace();
}
}
/**
* 回滚事务
*/
public void rollback(){
try {
connectionUtils.getThreadConnection().rollback();
} catch (SQLException e) {
e.printStackTrace();
}
}
/**
* 释放事务
*/
public void close(){
try {
connectionUtils.getThreadConnection().close();
connectionUtils.removeConnection();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
配置service和dao就不写了
3.factory
public class ServiceFactory {
private TransactionManager manager;
public void setManager(TransactionManager manager) {
this.manager = manager;
}
private AccountService accountService;
public final void setAccountService(AccountService accountService) {
this.accountService = accountService;
}
public AccountService getAccountService() {
return (AccountService) Proxy.newProxyInstance(accountService.getClass().getClassLoader(), accountService.getClass().getInterfaces(),
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object obj =null;
try {
//开启事务
System.out.println("哈哈哈哈");
manager.beginTransaction();
//执行操作
obj = method.invoke(accountService, args);
//提交事务
manager.commit();
System.out.println("哈哈哈哈");
//返回结果
return obj;
} catch (Exception e) {
//回滚操作
manager.rollback();
throw new RuntimeException("操作失败");
} finally {
//释放操作
manager.close();
}
}
}
);
}
}
4.配置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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="accountDao" class="top.chenyp.dao.impl.AccountDaoImpl">
<property name="connectionUtils" ref="connectionUtils"/>
<property name="queryRunner" ref="queryRunner"/>
</bean>
<bean id="proxyServiceFactory" factory-bean="serviceFactory" factory-method="getAccountService"/>
<bean id="serviceFactory" class="top.chenyp.factory.ServiceFactory">
<property name="manager" ref="transactionManager"/>
<property name="accountService" ref="accountService"/>
</bean>
<bean id="accountService" class="top.chenyp.service.impl.AccountServiceImpl">
<property name="accountDao" ref="accountDao"/>
</bean>
<bean id="connectionUtils" class="top.chenyp.utils.ConnectionUtils">
<property name="dataSource" ref="dataSource"/>
</bean>
<bean id="transactionManager" class="top.chenyp.utils.TransactionManager">
<property name="connectionUtils" ref="connectionUtils"/>
</bean>
<!-- 配置数据库的bean-->
<bean id="queryRunner" class="org.apache.commons.dbutils.QueryRunner" scope="prototype">
</bean>
<bean name="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="com.mysql.jdbc.Driver"/>
<property name="jdbcUrl" value="jdbc:mysql:///test"/>
<property name="user" value="root"/>
<property name="password" value="Cyp123.."/>
</bean>
</beans>
5.测试类
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:applicationContext.xml")
public class Test {
@Autowired
@Qualifier("proxyServiceFactory")
private AccountService accountService;
@org.junit.Test
public void test(){
accountService.test();
}
}