If it is necessary to ensure data security, but also to ensure performance, consider ThreadLocal (thread-local variables)
ThreadLocal: You can create a copy of each thread. Each thread can access its own internal copy.
That is new (created) once, ThreadLocal (copy) multiple times
For example: there is an information CSDN like to sell 100C coins, there are A, B, C three people do not buy a ThreadLocal to buy one, spent a total of 300C coins
Use the ThreadLocal, A is a buy and to copy and paste the two parts B, C. Took only money 100C
For a database, a connection corresponds to a transaction (database is a user-defined sequence of operation, either all these operations do, not to be incomplete.), A transaction may comprise a plurality of DML (Data Manipulation Language) operations.
Transaction process: open a transaction (manual submission will automatically be submitted →) → → various DML normal, just all DML will submit all
→ failure (abnormal) will just roll back all DML
public class JDBCUtils {
private static ComboPooledDataSource ds = new ComboPooledDataSource();
private static ThreadLocal<Connection> tl=new ThreadLocal<>(); //线程本地变量
/**
* 从线程中获取连接
* @return
* @throws SQLException
*/
public static Connection getConnection() throws SQLException {
//从线程中获取conneciton
Connection conn = tl.get(); //从tl中获取副本
if(conn==null){ //如果是第一次从tl里取连接
conn=ds.getConnection(); //通过数据源获取连接
//和当前线程绑定
tl.set(conn); //给tl中存放一个副本
}
return conn;
}
// 获取数据源
public static DataSource getDataSource() {
return ds;
}
// 释放资源
public static void closeResource( Statement st, ResultSet rs) {
closeResultSet(rs);
closeStatement(st);
}
// 释放资源
public static void closeResource(Connection conn, Statement st, ResultSet rs) {
closeResource(st, rs);
closeConn(conn);
}
// 释放 connection
public static void closeConn(Connection conn) {
if (conn != null) {
try {
conn.close();
//和线程解绑
tl.remove();
} catch (SQLException e) {
e.printStackTrace();
}
conn = null;
}
}
// 释放 statement ctrl + shift + f 格式化代码
public static void closeStatement(Statement st) {
if (st != null) {
try {
st.close();
} catch (SQLException e) {
e.printStackTrace();
}
st = null;
}
}
// 释放结果集
public static void closeResultSet(ResultSet rs) {
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
rs = null;
}
}
//开启事务(将自动提交方式 --→ 手动提交方式)
public static void startTransaction() throws SQLException{
getConnection().setAutoCommit(false); //true:自动 false:手动
}
/**
* 事务正常提交,且释放连接
*/
public static void commitAndClose(){
Connection conn = null;
try {
conn=getConnection();
//事务提交
conn.commit();
//关闭资源
conn.close();
//解除版定
tl.remove();
} catch (SQLException e) {
e.printStackTrace();
}
}
/**
* 事务提交失败(异常),回滚且释放资源
*/
public static void rollbackAndClose(){
Connection conn = null;
try {
conn=getConnection();
//事务回滚
conn.rollback();
//关闭资源
conn.close();
//解除版定
tl.remove();
} catch (SQLException e) {
e.printStackTrace();
}
}
public static void main(String[] args) throws SQLException {
//System.out.println(ds.getDataSourceName());
//System.out.println(ds.getJdbcUrl());
System.out.println(getConnection());
}
}
For more information about ThreadLocal can refer to this article https://blog.csdn.net/qq_23315711/article/details/78642171