JDBC中处理事务(事务中的connection必须是同一个)
相关方法
setAutoCommit(boolean)
如果true(默认值就是true)表示自动提交,con.setAutoCommit(false)
表示开启事务;
commit()
提交事务
rollback()
回滚事务
try {
con.setAutoCommit(false);//开启事务… mysql中开启是start transaction
//多个JDBC操作
con.commit();//try的最后提交事务 mysql 中提交 commit
} catch() {
con.rollback();//回滚事务 mysql rollback
}
JDBC中的线程处理
ThreadLocal:本地线程对象,内部变量是线程私有的,专属于每一个线程的。
现在JdbcUtils有个问题,如果有两个线程!第一个线程调用了beginTransaction()方法,另一个线程再调用beginTransaction()方法时,因为connection已经不再为null,所以就会抛出异常了。
我们希望JdbcUtils可以多线程环境下被使用!最好的方法是为每个线程提供一个Connection,这样每个线程都可以开启自己的事务了。
ThreadLocal类只有三个方法:
- void set(T value):保存值;
- T get():获取值;
- void remove():移除值。
JDBC工具类示例
import com.alibaba.druid.pool.DruidDataSourceFactory;
import javax.sql.DataSource;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
public class JdbcUtils {
private static DataSource dataSource;
private static ThreadLocal<Connection> tl = new ThreadLocal<Connection>();
static {
try {
Properties prop = new Properties();
InputStream in = JdbcUtils.class.getResourceAsStream("/jdbc.properties");
prop.load(in);
//创建DataSource
dataSource = DruidDataSourceFactory.createDataSource(prop);
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
//获取连接
public static Connection getConnection() throws SQLException {
Connection connection = tl.get();
if(connection != null) {
return connection;
}
return dataSource.getConnection();
}
//开启事务
public static void beginTransaction() throws SQLException {
Connection connection = tl.get();
if(connection != null) {
throw new SQLException("事务已经开启,在没有结束当前事务时,不能再开启事务!");
}
connection = dataSource.getConnection();
connection.setAutoCommit(false);
tl.set(connection);
}
//提交事务
public static void commitTransaction() throws SQLException {
Connection connection = tl.get();
if(connection == null) {
throw new SQLException("当前没有事务,所以不能提交事务!");
}
connection.commit();
connection.close();
tl.remove();
}
//回滚事务
public static void rollbackTransaction() throws SQLException {
Connection connection = tl.get();
if(connection == null) {
throw new SQLException("当前没有事务,所以不能回滚事务!");
}
connection.rollback();
connection.close();
tl.remove();
}
//释放资源
public static void close(Connection connection, Statement statement, ResultSet rSet) {
try {
if(rSet != null) {
rSet.close();
}
if(statement != null) {
statement.close();
}
if(connection != null) {
connection.close();
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}