當前位置:首頁 » 操作系統 » 多線程插入資料庫

多線程插入資料庫

發布時間: 2022-05-13 02:50:48

㈠ 請教如何進行多線程連接資料庫並寫入數據

#include <QCoreApplication>
#include "thread.h"
#include <QVector>
#include <QDebug>

int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);

QVector<Thread*> vector;
Thread *thread;

//創建多個線程,並start
for(int i=0;i<10;i++){
thread=new Thread;
vector.append(thread);
thread->set(i);
thread->start();
}

//等待所有線程執行完,然後刪除線程
foreach(thread,vector){
thread->wait();
}
foreach(thread,vector){
delete thread;
}

return a.exec();
}

-------------------------------------------------------------------------------------------------

#include "thread.h"

Thread::Thread(QObject *parent) : QThread(parent)
{
}

void Thread::run()
{
begin();
}

//為每個線程創建一個連接名
void Thread::set(int a)
{
connectionName=QString::number(a);
}

void Thread::connectionDatabase(QString dbName)
{
QsqlDatabasedb=QSqlDatabase::addDatabase("QMYSQL",connectionName);
db.setHostName("localhost");
db.setDatabaseName(dbName);
db.setUserName("root");
db.setPassword("");

if(!db.open())
qDebug()<<"db open fail";
}

void Thread::begin()
{
QString dbName="learnsql";
connectionDatabase(dbName);

QSqlDatabase db=QSqlDatabase::database(connectionName);
db.transaction(); //開啟事物

QSqlQuery query(db);

//向表student中插入10000條數據
for(int i=1;i<=10000;i++){
query.exec("insert into student values(1)");
}

db.commit(); //提交事物
}

㈡ 要瘋了,怎樣用多線程向MYSQL資料庫中寫入數據

在MySQL 8.0 之前, 我們假設一下有一條爛SQL,

mysqlselect * from t1 order by rand() ;

以多個線程在跑,導致CPU被跑滿了,其他的請求只能被阻塞進不來。那這種情況怎麼辦?


大概有以下幾種解決辦法:

  • 設置max_execution_time 來阻止太長的讀SQL。那可能存在的問題是會把所有長SQL都給KILL 掉。有些必須要執行很長時間的也會被誤殺。

  • 自己寫個腳本檢測這類語句,比如order by rand(), 超過一定時間用Kill query thread_id 給殺掉。

  • 那能不能不要殺掉而讓他正常運行,但是又不影響其他的請求呢?

    那mysql 8.0 引入的資源組(resource group,後面簡寫微RG)可以基本上解決這類問題。

    比如我可以用 RG 來在SQL層面給他限制在特定的一個CPU核上,這樣我就不管他,讓他繼續運行,如果有新的此類語句,讓他排隊好了。

    為什麼說基本呢?目前只能綁定CPU資源,其他的暫時不行。

    那我來演示下如何使用RG。

    創建一個資源組user_ytt. 這里解釋下各個參數的含義,

  • type = user 表示這是一個用戶態線程,也就是前台的請求線程。如果type=system,表示後台線程,用來限制mysql自己的線程,比如Innodb purge thread,innodb read thread等等。

  • vcpu 代表cpu的邏輯核數,這里0-1代表前兩個核被綁定到這個RG。可以用lscpu,top等列出自己的CPU相關信息。

  • thread_priority 設置優先順序。user 級優先順序設置大於0。

  • mysqlmysql> create resource group user_ytt type = user vcpu = 0-1 thread_priority=19 enable;Query OK, 0 rows affected (0.03 sec)


  • RG相關信息可以從 information_schema.resource_groups 系統表裡檢索。

  • mysqlmysql> select * from information_schema.resource_groups;+---------------------+---------------------+------------------------+----------+-----------------+| RESOURCE_GROUP_NAME | RESOURCE_GROUP_TYPE | RESOURCE_GROUP_ENABLED | VCPU_IDS | THREAD_PRIORITY |+---------------------+---------------------+------------------------+----------+-----------------+| USR_default | USER | 1 | 0-3 | 0 || SYS_default | SYSTEM | 1 | 0-3 | 0 || user_ytt | USER | 1 | 0-1 | 19 |+---------------------+---------------------+------------------------+----------+-----------------+3 rows in set (0.00 sec)


  • 我們來給語句select guid from t1 group by left(guid,8) order by rand() 賦予RG user_ytt。

  • mysql> show processlist;+-----+-----------------+-----------+------+---------+-------+------------------------+-----------------------------------------------------------+| Id | User | Host | db | Command | Time | State | Info |+-----+-----------------+-----------+------+---------+-------+------------------------+-----------------------------------------------------------+| 4 | event_scheler | localhost | NULL | Daemon | 10179 | Waiting on empty queue | NULL || 240 | root | localhost | ytt | Query | 101 | Creating sort index | select guid from t1 group by left(guid,8) order by rand() || 245 | root | localhost | ytt | Query | 0 | starting | show processlist |+-----+-----------------+-----------+------+---------+-------+------------------------+-----------------------------------------------------------+3 rows in set (0.00 sec)


  • 找到連接240對應的thread_id。

  • mysqlmysql> select thread_id from performance_schema.threads where processlist_id = 240;+-----------+| thread_id |+-----------+| 278 |+-----------+1 row in set (0.00 sec)


  • 給這個線程278賦予RG user_ytt。沒報錯就算成功了。

  • mysqlmysql> set resource group user_ytt for 278;Query OK, 0 rows affected (0.00 sec)


  • 當然這個是在運維層面來做的,我們也可以在開發層面結合 MYSQL HINT 來單獨給這個語句賦予RG。比如:

  • mysqlmysql> select /*+ resource_group(user_ytt) */guid from t1 group by left(guid,8) order by rand()....8388602 rows in set (4 min 46.09 sec)


  • RG的限制:

  • Linux 平台上需要開啟 CAPSYSNICE 特性。比如我機器上用systemd 給mysql 服務加上

    systemctl edit mysql@80 [Service]AmbientCapabilities=CAP_SYS_NICE

  • mysql 線程池開啟後RG失效。

  • freebsd,solaris 平台thread_priority 失效。

  • 目前只能綁定CPU,不能綁定其他資源。

㈢ 如何在多線程操作資料庫

通常,最好避免鎖定 public 類型或鎖定不受應用程序控制的對象實例。例如,如果該實例可以被公開訪問,則 lock(this) 可能會有問題,因為不受控制的代碼也可能會鎖定該對象。這可能導致死鎖,即兩個或更多個線程等待釋放同一對象。出於同樣的原因,鎖定公共數據類型(相比於對象)也可能導致問題。鎖定字元串尤其危險,因為字元串被公共語言運行庫 (CLR)「暫留」。這意味著整個程序中任何給定字元串都只有一個實例,就是這同一個對象表示了所有運行的應用程序域的所有線程中的該文本。因此,只要在應用程序進程中的任何位置處具有相同內容的字元串上放置了鎖,就將鎖定應用程序中該字元串的所有實例。因此,最好鎖定不會被暫留的私有或受保護成員。某些類提供專門用於鎖定的成員。例如,Array 類型提供 SyncRoot。許多集合類型也提供 SyncRoot。

java 多線程 寫入資料庫 數據池

你這個首先得分開。
第一部分:你有很多線程在往數據池裡面寫入數據。那麼,你的線程只管寫數據,不用理會其他的數據。
第二部分:你的另外的線程(這里可以用spring的job定時器啟動),這部分只管往資料庫寫入數據,至於寫入的條件,你可以判斷數據池的數據是否達到寫入的標准。這里的線程可以配置為啟動一次就一直運行,或者是隔多少秒繼續運行。這樣可以提高效率。
第三部分:數據池,這里的數據池一定要第一部分和第二部分的線程都能夠訪問,並且是唯一的。你可以寫一個公用的類來進行控制。
大致就是這樣的。

㈤ 關於多線程對mysql資料庫插入操作的一個疑問。

資料庫有自己的連接鎖機制,如果是針對同一台機器使用同一個介面進行插入的話多線程和單線程是一樣的。除非你有好幾台資料庫伺服器,這樣再使用多線程來進行上面的工作的話效率才會明顯提高。

㈥ delphi怎樣使用多線程寫入ACCESS資料庫

你用兩個ADO連接組件,一個連接SQL,一個連接ACCESS;然後用兩個ADOdataset組件,一個與SQLADO連接組件連接,另外一個與ACCESS的鏈接組件連接,各自打開要讀寫的表,然後用一個FOR循環,讀寫,這和從界面上錄入數據然後保存,沒有什麼兩樣.

㈦ java怎麼多線程操作一個資料庫

//將資料庫中的數據條數分段
public void division(){
//獲取要導入的總的數據條數
String sql3="SELECT count(*) FROM [CMD].[dbo].[my1]";
try {
pss=cons.prepareStatement(sql3);
rss=pss.executeQuery();

while(rss.next()){
System.out.println("總記錄條數:"+rss.getInt(1));
sum=rss.getInt(1);
}
//每30000條記錄作為一個分割點
if(sum>=30000){
n=sum/30000;
resie=sum%30000;
}else{
resie=sum;
}

System.out.println(n+" "+resie);

} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}
線程類
public MyThread(int start,int end) {
this.end=end;
this.start=start;
System.out.println("處理掉余數");
try {

System.out.println("--------"+Thread.currentThread().getName()+"------------");
Class.forName(SQLSERVERDRIVER);
System.out.println("載入sqlserver驅動...");
cons = DriverManager.getConnection(CONTENTS,UNS,UPS);
stas = cons.createStatement();
System.out.println("連接SQLServer資料庫成功!!");

System.out.println("載入mysql驅動.....");
Class.forName(MYSQLDRIVER);
con = DriverManager.getConnection(CONTENT,UN,UP);
sta = con.createStatement();
// 關閉事務自動提交
con.setAutoCommit(false);
System.out.println("連接mysql資料庫成功!!");

} catch (Exception e) {
e.printStackTrace();
}
// TODO Auto-generated constructor stub
}

public ArrayList<Member> getAll(){
Member member;
String sql1="select * from (select row_number() over (order by pmcode) as rowNum,*" +
" from [CMD].[dbo].[my1]) as t where rowNum between "+start+" and "+end;
try {
System.out.println("正在獲取數據...");
allmembers=new ArrayList();
rss=stas.executeQuery(sql1);
while(rss.next()){
member=new Member();
member.setAddress1(rss.getString("address1"));
member.setBnpoints(rss.getString("bnpoints"));
member.setDbno(rss.getString("dbno"));
member.setExpiry(rss.getString("expiry"));
member.setHispoints(rss.getString("hispoints"));
member.setKypoints(rss.getString("kypoints"));
member.setLevels(rss.getString("levels"));
member.setNames(rss.getString("names"));
member.setPmcode(rss.getString("pmcode"));
member.setRemark(rss.getString("remark"));
member.setSex(rss.getString("sex"));
member.setTelephone(rss.getString("telephone"));
member.setWxno(rss.getString("wxno"));
member.setPmdate(rss.getString("pmdate"));
allmembers.add(member);
// System.out.println(member.getNames());
}
System.out.println("成功獲取sqlserver資料庫數據!");
return allmembers;

} catch (SQLException e) {
// TODO Auto-generated catch block
System.out.println("獲取sqlserver資料庫數據發送異常!");
e.printStackTrace();
}
try {
rss.close();
stas.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}

public void inputAll(ArrayList<Member> allmembers){
System.out.println("開始向mysql中寫入");
String sql2="insert into test.my2 values (?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
try {
ps=con.prepareStatement(sql2);
System.out.println("-------------------------等待寫入數據條數: "+allmembers.size());
for(int i=0;i<allmembers.size();i++){
ps.setString(1, allmembers.get(i).getPmcode());
ps.setString(2, allmembers.get(i).getNames());
//System.out.println(allmembers.get(i).getNames());
ps.setString(3, allmembers.get(i).getSex());
ps.setString(4, allmembers.get(i).getTelephone());
ps.setString(5, allmembers.get(i).getAddress1());
ps.setString(6, allmembers.get(i).getPmdate());
ps.setString(7, allmembers.get(i).getExpiry());
ps.setString(8, allmembers.get(i).getLevels());
ps.setString(9, allmembers.get(i).getDbno());
ps.setString(10, allmembers.get(i).getHispoints());
ps.setString(11, allmembers.get(i).getBnpoints());
ps.setString(12, allmembers.get(i).getKypoints());
ps.setString(13, allmembers.get(i).getWxno());
ps.setString(14, allmembers.get(i).getRemark());
//插入命令列表
//ps.addBatch();
ps.executeUpdate();
}
//ps.executeBatch();
con.commit();

ps.close();
con.close();
this.flag=false;
System.out.println(Thread.currentThread().getName()+"--->OK");
} catch (SQLException e) {
// TODO Auto-generated catch block
System.out.println("向mysql中更新數據時發生異常!");
e.printStackTrace();
}
}
@Override
public void run() {
// TODO Auto-generated method stub
while(true&&flag){
this.inputAll(getAll());
}
}

㈧ 為什麼多線程插入資料庫,很容易失敗

數據插入和修改刪除的時候資料庫會有個事務鎖,如果多個鎖並發操作會引起死鎖,那麼直接後果就是插入失敗

㈨ 如何利用多線程提高DB插入數據的效率

使用多線程提高資料庫操作效率,可以每個線程負責一個插入語句(用一個分配器將每條插入語句分配給不同線程),共享一個DB的操作句柄。

需要注意的是,如果你的數據插入有互斥,例如有唯一性的主鍵或者索引,那麼資料庫在實際執行的時候還是全表加鎖的。

㈩ java 多線程操作資料庫

//將資料庫中的數據條數分段
publicvoiddivision(){
//獲取要導入的總的數據條數
Stringsql3="SELECTcount(*)FROM[CMD].[dbo].[my1]";
try{
pss=cons.prepareStatement(sql3);
rss=pss.executeQuery();

while(rss.next()){
System.out.println("總記錄條數:"+rss.getInt(1));
sum=rss.getInt(1);
}
//每30000條記錄作為一個分割點
if(sum>=30000){
n=sum/30000;
resie=sum%30000;
}else{
resie=sum;
}

System.out.println(n+""+resie);

}catch(SQLExceptione){
//TODOAuto-generatedcatchblock
e.printStackTrace();
}

}
線程類
publicMyThread(intstart,intend){
this.end=end;
this.start=start;
System.out.println("處理掉余數");
try{

System.out.println("--------"+Thread.currentThread().getName()+"------------");
Class.forName(SQLSERVERDRIVER);
System.out.println("載入sqlserver驅動...");
cons=DriverManager.getConnection(CONTENTS,UNS,UPS);
stas=cons.createStatement();
System.out.println("連接SQLServer資料庫成功!!");

System.out.println("載入mysql驅動.....");
Class.forName(MYSQLDRIVER);
con=DriverManager.getConnection(CONTENT,UN,UP);
sta=con.createStatement();
//關閉事務自動提交
con.setAutoCommit(false);
System.out.println("連接mysql資料庫成功!!");

}catch(Exceptione){
e.printStackTrace();
}
//TODOAuto-generatedconstructorstub
}


publicArrayList<Member>getAll(){
Membermember;
Stringsql1="select*from(selectrow_number()over(orderbypmcode)asrowNum,*"+
"from[CMD].[dbo].[my1])astwhererowNumbetween"+start+"and"+end;
try{
System.out.println("正在獲取數據...");
allmembers=newArrayList();
rss=stas.executeQuery(sql1);
while(rss.next()){
member=newMember();
member.setAddress1(rss.getString("address1"));
member.setBnpoints(rss.getString("bnpoints"));
member.setDbno(rss.getString("dbno"));
member.setExpiry(rss.getString("expiry"));
member.setHispoints(rss.getString("hispoints"));
member.setKypoints(rss.getString("kypoints"));
member.setLevels(rss.getString("levels"));
member.setNames(rss.getString("names"));
member.setPmcode(rss.getString("pmcode"));
member.setRemark(rss.getString("remark"));
member.setSex(rss.getString("sex"));
member.setTelephone(rss.getString("telephone"));
member.setWxno(rss.getString("wxno"));
member.setPmdate(rss.getString("pmdate"));
allmembers.add(member);
//System.out.println(member.getNames());
}
System.out.println("成功獲取sqlserver資料庫數據!");
returnallmembers;

}catch(SQLExceptione){
//TODOAuto-generatedcatchblock
System.out.println("獲取sqlserver資料庫數據發送異常!");
e.printStackTrace();
}
try{
rss.close();
stas.close();
}catch(SQLExceptione){
//TODOAuto-generatedcatchblock
e.printStackTrace();
}
returnnull;
}

publicvoidinputAll(ArrayList<Member>allmembers){
System.out.println("開始向mysql中寫入");
Stringsql2="insertintotest.my2values(?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
try{
ps=con.prepareStatement(sql2);
System.out.println("-------------------------等待寫入數據條數:"+allmembers.size());
for(inti=0;i<allmembers.size();i++){
ps.setString(1,allmembers.get(i).getPmcode());
ps.setString(2,allmembers.get(i).getNames());
//System.out.println(allmembers.get(i).getNames());
ps.setString(3,allmembers.get(i).getSex());
ps.setString(4,allmembers.get(i).getTelephone());
ps.setString(5,allmembers.get(i).getAddress1());
ps.setString(6,allmembers.get(i).getPmdate());
ps.setString(7,allmembers.get(i).getExpiry());
ps.setString(8,allmembers.get(i).getLevels());
ps.setString(9,allmembers.get(i).getDbno());
ps.setString(10,allmembers.get(i).getHispoints());
ps.setString(11,allmembers.get(i).getBnpoints());
ps.setString(12,allmembers.get(i).getKypoints());
ps.setString(13,allmembers.get(i).getWxno());
ps.setString(14,allmembers.get(i).getRemark());
//插入命令列表
//ps.addBatch();
ps.executeUpdate();
}
//ps.executeBatch();
con.commit();

ps.close();
con.close();
this.flag=false;
System.out.println(Thread.currentThread().getName()+"--->OK");
}catch(SQLExceptione){
//TODOAuto-generatedcatchblock
System.out.println("向mysql中更新數據時發生異常!");
e.printStackTrace();
}
}
@Override
publicvoidrun(){
//TODOAuto-generatedmethodstub
while(true&&flag){
this.inputAll(getAll());
}
}

熱點內容
集群伺服器地址都是一樣的嗎 發布:2024-10-10 01:07:39 瀏覽:325
java怎麼開平方 發布:2024-10-10 01:02:25 瀏覽:486
windowsserver更新伺服器搭建 發布:2024-10-10 00:42:32 瀏覽:657
kz解壓縮 發布:2024-10-10 00:27:19 瀏覽:668
方舟編譯器呢 發布:2024-10-10 00:13:41 瀏覽:914
阿里雲伺服器安裝圖形 發布:2024-10-09 23:40:45 瀏覽:863
cb編譯器怎麼下 發布:2024-10-09 23:37:38 瀏覽:8
編譯translation 發布:2024-10-09 23:24:23 瀏覽:10
伺服器cpu能供多少電腦使用 發布:2024-10-09 23:05:21 瀏覽:352
演算法和嵌入式 發布:2024-10-09 23:04:34 瀏覽:557