日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

mysql多线程使用一个链接_探索多线程使用同一个数据库connection的后果

發(fā)布時間:2025/3/8 数据库 16 豆豆
生活随笔 收集整理的這篇文章主要介紹了 mysql多线程使用一个链接_探索多线程使用同一个数据库connection的后果 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

在項目中看到有用到數(shù)據(jù)庫的連接池,心里就思考著為什么需要數(shù)據(jù)庫連接池,只用一個連接會造成什么影響?(只用一個connection)?

1? 猜想:jdbc的事務是基于connection的,如果多線程共用一個connection,會造成多線程之間的事務相互干擾。(connection.setAutoCommit(false);//connection.commit())

2? 于是就模仿以下場景來做一個測試:

在多用戶請求的情況下,只用一個數(shù)據(jù)庫connection。

1)獲取connection工具類:

package jdbcPool.util;

import java.sql.Connection;

import java.sql.DriverManager;

import java.sql.SQLException;

public class ConnectorUtil {

public static final String user="root";

public static final String pwd="123456";

public static final String driver="com.mysql.jdbc.Driver";

public static final String url ="jdbc:mysql://localhost:3306/test";

private static Connection conn;

private static int connectCount=0;

static {

try {

Class.forName(driver);

} catch (ClassNotFoundException e) {

System.out.println("找不到數(shù)據(jù)庫驅(qū)動..");

e.printStackTrace();

}

}

/**

* 獲取數(shù)據(jù)庫連接實例

* @return

*/

public synchronized static Connection getInstance(){

if(conn==null){

try {

conn=DriverManager.getConnection(url,user, pwd);

conn.setAutoCommit(false);//設置為不自動提交。。。

connectCount++;

System.out.println("連接數(shù)據(jù)庫次數(shù):"+connectCount);

} catch (SQLException e) {

System.out.println("連接數(shù)據(jù)庫失敗....");

e.printStackTrace();

}

}

return conn;

}

}

2) 業(yè)務接口實現(xiàn)類:

package jdbcPool.business;

import java.sql.Connection;

import java.sql.SQLException;

import java.sql.Statement;

import jdbcPool.util.ConnectorUtil;

public class StudentService {

private Connection conn;

private static StudentService studentService;

private StudentService(){

conn=ConnectorUtil.getInstance();

}

public static synchronized? StudentService getInstance(){

if(studentService==null){

studentService=new StudentService();

}

return studentService;

}

public void insert(String id,String name,String no) throws Exception {

String addStr ="insert into student(id,name,no) values('"+id+"','"+name+"','"+no+"')";

Statement statement=null;

try {

statement = conn.createStatement();

statement.execute(addStr);

if("1350".equals(id)){//模仿某個線程執(zhí)行service某個方法中某個步驟出現(xiàn)異常

Thread.sleep(3000);//模仿當前線程執(zhí)行時間較長。。。。。

System.out.println("發(fā)生異常。。。。。");

System.out.println("記錄"+id+"插入失敗。。。。");

conn.rollback();? //出現(xiàn)異常事務回滾。。。

throw new Exception();

}else{

conn.commit();

System.out.println("記錄"+id+"插入成功。。。。");

}

} catch (SQLException e) {

System.out.println("創(chuàng)建statement失敗");

e.printStackTrace();

}finally{

if(statement!=null){

try {

statement.close();

} catch (SQLException e) {

e.printStackTrace();

}

}

}

}

}

3)模擬用戶請求的線程類:

package jdbcPool.thread;

import jdbcPool.business.StudentService;

public class Request implements Runnable{

private String id;

public Request(String id) {

this.id=id;

}

@Override

public void run() {

//模仿service的單例模式

try {

StudentService.getInstance().insert(this.id, "name"+id, "no"+id);

} catch (Exception e) {

e.printStackTrace();

}

}

}

4) 測試類:

package jdbcPool.test;

import jdbcPool.thread.Request;

public class Main {

//兩百個線程并發(fā)訪問同一個connection

public static void main(String[] args){

for(int i=1300;i<1500;i++){

Thread th=new Thread(new Request(String.valueOf(i)));

th.start();

}

}

}

5)結(jié)果分析:

打印臺出現(xiàn)的結(jié)果:

記錄1489插入成功。。。。

記錄1490插入成功。。。。

記錄1491插入成功。。。。

記錄1495插入成功。。。。

記錄1492插入成功。。。。

記錄1493插入成功。。。。

記錄1494插入成功。。。。

記錄1496插入成功。。。。

記錄1497插入成功。。。。

記錄1498插入成功。。。。

記錄1499插入成功。。。。

記錄1300插入成功。。。。

發(fā)生異常。。。。。

記錄1350插入失敗。。。。

java.lang.Exception

at jdbcPool.business.StudentService.insert(StudentService.java:38)

at jdbcPool.thread.Request.run(Request.java:18)

at java.lang.Thread.run(Unknown Source)

數(shù)據(jù)庫中的表數(shù)據(jù):

id為1350的記錄竟然成功的添加進數(shù)據(jù)庫了,造成這一現(xiàn)象的原因顯然是

在添加id為1350的記錄的線程遇到異常還沒有來得及數(shù)據(jù)回滾時,

別的線程先調(diào)用了 connection.commit()方法,以至于把不該提交的數(shù)據(jù)提交到數(shù)據(jù)庫了。

6)? 總結(jié):在多線程的環(huán)境中,在不對connection做線程安全處理的情況下,使用單個connection會引起事務的混亂....影響jdbc事務的使用。。。

總結(jié)

以上是生活随笔為你收集整理的mysql多线程使用一个链接_探索多线程使用同一个数据库connection的后果的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。