多線程資料庫連接
是的。肯定要每次都連接資料庫,簡單點
你可以把連接資料庫寫成一個類中的方法,到run()線程的時候,創建類的對象,再調用就好了。
② 大家是如何處理很多線程連接資料庫連接的
連接資料庫要連接池,就是connection對象要放在一個LinkedList裡面,然後每個線程一個。這個這個List被封裝在一個單例模式的對象里。線程要是共享connection,要是搞起並發來,一下子就掛了。
③ 多線程並發訪問資料庫中不同記錄時應該採用什麼辦法
多個線程在訪問同一個資料庫中的記錄的時候,在大並發的情況下,一定要做好事務機制。要不然後果還是很扎心的。可能遇到這樣的問題的時候首先想到的就是同步鎖機制了。
並發產生的情況
其實在實際項目開發匯總,首先要做的就是避免多個線程共用一個資料庫連接,這樣會很容易出問題,最好是一個線程一個連接。在必要的時候需要線程同步或存儲過程加鎖。如果有比較復雜的事務操作的話就需要加鎖了,如果不加的話就會出現你說的臟讀、死鎖等問題。
④ 請教如何進行多線程連接資料庫並寫入數據
#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(); //提交事物
}
⑤ 多線程如何並發訪問SQLite資料庫
SQLite作為一款小型的嵌入式資料庫,本身沒有提供復雜的鎖定機制,無法內部管理多路並發下的數據操作同步問題,更談不上優化,所以涉及到多路並發的情況,需要外部進行讀寫鎖控制,否則SQLite會返回SQLITE_BUSY錯誤,以駁回相關請求。
返回SQLITE_BUSY主要有以下幾種情況:
1。當有寫操作時,其他讀操作會被駁回
2。當有寫操作時,其他寫操作會被駁回
3。當開啟事務時,在提交事務之前,其他寫操作會被駁回
4。當開啟事務時,在提交事務之前,其他事務請求會被駁回
5。當有讀操作時,其他寫操作會被駁回
6。讀操作之間能夠並發執行
基於以上討論,可以看出這是一個典型的讀者寫者問題,讀操作要能夠共享,寫操作要互斥,讀寫之間也要互斥
可以設計如下的方案解決並發操作資料庫被鎖定的問題,同時保證讀操作能夠保持最大並發
1。採用互斥鎖控制資料庫寫操作
2。只有擁有互斥鎖的線程才能夠操作資料庫
3。寫操作必須獨立擁有互斥鎖
4。讀操作必須能夠共享互斥鎖,即在第一次讀取的時候獲取互斥鎖,最後一次讀取的時候釋放互斥鎖
⑥ 多線程訪問資料庫問題
這個要看情況。
不同的資料庫情況不一樣。
一般說來是可以每個線程使用一個連接的(有時候會出現很難查找的奇怪問題)
保險一點還是共用一個連接 互斥佔用。
⑦ java爬蟲採用多線程,資料庫連接多了就報異常
可以通過測試對錯誤原因進行排查,如果連接少量時不出問題,那就是連接量超出了某一數值出現異常,可以查看資料庫的鏈接上限,如果是連接上限原因,可以嘗試上調上限或者降低連接數量
⑧ 多線程 連接資料庫,C#多線程寫資料庫
多線程連接資料庫的連接池類:
public static class ConnectionPool
{
private static object locker = new object();
private static Dictionary<string, SqlConnection> Connections = null;
public static SqlConnection GetConnection<T>() where T : class, new()
{
string databaseName = NA.Common.Extensions.GetDatabaseName<T>();
if (string.IsNullOrEmpty(databaseName))
return null;
if (Connections == null)
{
lock (locker)
{
Connections = new Dictionary<string, SqlConnection>();
}
}
string connKey = FindFreeSqlConnection(databaseName);
if (connKey != null)
return Connections[connKey];
else
{
string strconn = NA.Common.Extensions.GetConnectionString<T>();
int poolSize = NA.Common.Extensions.GetConnectionPoolSize<T>();
lock (locker)
{
for (int i = 0; i < poolSize; ++i)
{
SqlConnection conn = new SqlConnection(strconn);
conn.Open();
Connections.Add(databaseName + "_" + i.ToString(), conn);
conn.Close();
}
}
return Connections[FindFreeSqlConnection(databaseName)];
}
}
private static string FindFreeSqlConnection(string databaseName)
{
IEnumerable<string> connKeys = Connections.Keys.Where(item => item.StartsWith(databaseName));
if (connKeys != null && connKeys.Count() > 0)
{
foreach (string key in connKeys)
{
if (Connections[key].State == ConnectionState.Closed)
return key;
}
}
return null;
}
}
附加上其中用到的三個方法:
internal static int GetConnectionPoolSize<T>() where T : class, new()
{
string database = GetDatabaseName<T>();
string[] poolSizeArray = ConfigurationManager.AppSettings["ConnectionsPoolSize"].Split('|');
if (poolSizeArray != null)
{
foreach (string sizeItem in poolSizeArray)
{
string[] sizeItemArray = sizeItem.Split(':');
if (database == sizeItemArray[0])
return int.Parse(sizeItemArray[1]);
}
}
return 50;
}
public static string GetConnectionString<T>() where T : class, new()
{
string tableName = GetTableName<T>();
string[] databaseArray = ConfigurationManager.AppSettings["DatabaseArray"].Split('|');
if (databaseArray != null)
{
foreach (string database in databaseArray)
{
string tableNameList = ConfigurationManager.AppSettings[database];
string[] tables = ConfigurationManager.AppSettings[database].Split('|');
if (tables != null && tables.Length > 0)
if (tables.Contains(tableName))
return ConfigurationManager.ConnectionStrings[database].ConnectionString;
}
}
return string.Empty;
}
public static string GetDatabaseName<T>() where T : class, new()
{
string tableName = GetTableName<T>();
string[] databaseArray = ConfigurationManager.AppSettings["DatabaseArray"].Split('|');
if (databaseArray != null)
{
foreach (string database in databaseArray)
{
string tableNameList = ConfigurationManager.AppSettings[database];
string[] tables = ConfigurationManager.AppSettings[database].Split('|');
if (tables != null && tables.Length > 0)
if (tables.Contains(tableName))
return database;
}
}
return string.Empty;
}