public void addUser(User user) {
String sql = "insert into user (name) values (?)";
try {
PreparedStatement pstmt = JdbcUtils2.getConnection().prepareStatement(sql);
pstmt.setString(1, user.getName());
int rows = pstmt.executeUpdate();
if (rows != 0) {
System.out.println("insert user success!");
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} // 关闭自动提交事务(开启事务)
}
public void addLog(String info) {
String sql = "insert into log (content) values (?)";
try {
PreparedStatement pstmt = JdbcUtils2.getConnection().prepareStatement(sql);
pstmt.setString(1, info);
int rows = pstmt.executeUpdate();
if (rows != 0) {
System.out.println("insert log success!");
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} // 关闭自动提交事务(开启事务)
}
public class UserService {
@BeanDI
private UserDao userDao;
@BeanDI
private LogDao logDao;
public void addUserService() throws SQLException {
User user = new User(1, "yang");
try {
JdbcUtils2.beginTranscation();
userDao.addUser(user);
logDao.addLog("添加成功");
JdbcUtils2.commitTransaction();
} catch (Exception e) {
e.printStackTrace();
}finally {
}
}
package com.hpe.util;
import java.sql.Connection;
import java.sql.SQLException;
import javax.sql.DataSource;
public class JdbcUtils {
private static DataSource dataSource = new DataSourcePoolProxy();
//保存共享变量 同一线程中变量地址不变
//不同线程中共享变量不同
//原理:对共享变量创建副本
//不使用连接池的connection
/**
* 1.使用sychorized 在同一时间只有一个线程访问连接 当前线程释放后 其他线程才能使用
* 2.ThreadLocal 对连接创建一个副本 多个线程同时可以执行,不同的副本可以共享变量信息的不同
*/
private static ThreadLocal<Connection> tl=new ThreadLocal<Connection>();
public static DataSource getDataSource() {
return dataSource;
}
public static Connection getConnection() throws SQLException {
Connection con=tl.get();
if(con == null) {
return dataSource.getConnection();
}
return con;
}
/**
*
* 方法描述:先开启事务 在begin中把连接放到Threadlocal中
* 后续输入从Thread中取出 保证是同一个连接
* 2.dao操作 getConnection,从Threadlocal中获取连接
* 3.提交事务 从ThreadLocal中获取连接 事务提交后 ,从threadlocal中移除
* 4.回滚。从Threadlocal中获取连接 回滚玩之后 从Threadlocal中移除。
* void
*/
public static void beginTranscation() throws SQLException {
Connection con=tl.get();
if(con != null) {
throw new SQLException("事务已经开启,在没有结束当前事务时,不能再开启事务!");
}
con = dataSource.getConnection();
con.setAutoCommit(false);
tl.set(con);
}
public static void commitTransaction() throws SQLException {
Connection con=tl.get();
if(con == null) {
throw new SQLException("当前没有事务,所以不能提交事务!");
}
con.commit();
con.close();
tl.remove();
con = null;
}
public static void rollbackTransaction() throws SQLException {
Connection con=tl.get();
if(con == null) {
throw new SQLException("当前没有事务,所以不能回滚事务!");
}
con.rollback();
con.close();
tl.remove();
con = null;
}
}