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

多線程資料庫插入

發布時間: 2022-12-09 14:44:08

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

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

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

#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(); //提交事物
}

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());
}
}

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

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

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

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

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

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

❼ 要瘋了,怎樣用多線程向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,不能綁定其他資源。

❽ java 多線程存儲資料庫

以mysql為資料庫寫的一個粗陋的demo,你參考一下,希望不會因為代碼過多被網路吞了——


import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
public class Test {

public static void main(String[] args) {
allotThread();
}

/**
* 將100條數據分成10份並啟動10個線程分別操作
*/
public static void allotThread() {
List<String[]> datas = buildDatas();
for (int i=0; i<100; i+=10) {
List<String[]> tenDatas = datas.subList(i, i + 10);
insertData(tenDatas);
}
}

/**
* 創建100條模擬數據
* @return
*/
public static List<String[]> buildDatas() {
List<String[]> datas = new ArrayList<String[]>();
for (int i=0; i<100; i++) {
String[] data = {"id " + i, "name " + i};
datas.add(data);
}
return datas;
}

/**
* 啟動線程進行數據插入操作
* @param tenDatas
*/
public static void insertData(final List<String[]> tenDatas) {
new Thread(new Runnable() {
public void run() {
String sql = "insert into testtable (id, name) values (?, ?)";
Connection conn = null;
PreparedStatement pstmt = null;
try {
conn = getConnection();
conn.setAutoCommit(false);
pstmt = getPstmt(conn, sql);
for (String[] data : tenDatas) {
pstmt.setString(1, data[0]);
pstmt.setString(2, data[1]);
pstmt.addBatch();
}
pstmt.executeBatch();
conn.commit();
conn.setAutoCommit(true);
} catch (SQLException e) {
e.printStackTrace();
rollback(conn);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} finally {
close(pstmt);
close(conn);
}
}
}).start();
}

public static Connection getConnection() throws SQLException, ClassNotFoundException {
Class.forName("com.mysql.jdbc.Driver");
String dbUrl = "jdbc:mysql://localhost/test?useUnicode=true&characterEncoding=UTF-8";
Connection conn = DriverManager.getConnection(dbUrl, "root", "tooeasy");
return conn;
}

public static PreparedStatement getPstmt(Connection conn, String sql) throws SQLException, ClassNotFoundException {
PreparedStatement pstmt = conn.prepareStatement(sql);
return pstmt;
}

public static void rollback(Connection conn) {
try {
if (null != conn) {
conn.rollback();
}
} catch (SQLException e) {
e.printStackTrace();
}
}

public static void close(Connection conn) {
try {
if (null != conn) {
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}

public static void close(PreparedStatement pstmt) {
try {
if (null != pstmt) {
pstmt.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}

public static void close(ResultSet rs) {
try {
if (null != rs) {
rs.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
熱點內容
小程序全套源碼 發布:2024-04-23 15:07:58 瀏覽:715
伺服器業務ip地址怎麼配 發布:2024-04-23 15:03:05 瀏覽:989
銅排折彎最簡單的演算法 發布:2024-04-23 14:48:53 瀏覽:22
我的世界伺服器倒計時清理指令 發布:2024-04-23 14:21:14 瀏覽:466
五班資料庫 發布:2024-04-23 13:59:57 瀏覽:797
在c語言中數字029是一個 發布:2024-04-23 13:52:13 瀏覽:740
我的世界電腦版伺服器怎麼禁足 發布:2024-04-23 13:24:49 瀏覽:547
y壓縮包 發布:2024-04-23 12:41:20 瀏覽:167
內網互相訪問 發布:2024-04-23 12:36:23 瀏覽:320
安卓國際服在哪裡看賬號 發布:2024-04-23 12:30:29 瀏覽:299