您可以在多线程代码或重入代码中使用嵌入式 SQL 语句。但是,如果您使用单个连接,则对于每个连接您只能有一个活动请求。在多线程应用程序中,除非使用信号控制访问,否则在每个线程上不应使用到数据库的同一连接。
对于在希望使用数据库的每个线程上使用单独的连接没有限制。运行时库使用 SQLCA 来区分不同的线程上下文。因此,希望并行使用数据库的每个线程都必须具有自己的 SQLCA。
任何给定的数据库连接都只能从一个 SQLCA 访问,但取消指令除外,此指令必须从单独的线程发出。
有关取消请求的信息,请参见实现请求管理。
以下是一个多线程嵌入式 SQL 重入代码的示例。
#include <stdio.h> #include <string.h> #include <malloc.h> #include <ctype.h> #include <stdlib.h> #include <process.h> #include <windows.h> EXEC SQL INCLUDE SQLCA; EXEC SQL INCLUDE SQLDA; #define TRUE 1 #define FALSE 0 // multithreading support typedef struct a_thread_data { SQLCA sqlca; int num_iters; int thread; int done; } a_thread_data; // each thread's ESQL test EXEC SQL SET SQLCA "&thread_data->sqlca"; static void PrintSQLError( a_thread_data * thread_data ) /******************************************************/ { char buffer[200]; printf( "%d: SQL error %d -- %s ... aborting\n", thread_data->thread, SQLCODE, sqlerror_message( &thread_data->sqlca, buffer, sizeof( buffer ) ) ); exit( 1 ); } EXEC SQL WHENEVER SQLERROR { PrintSQLError( thread_data ); }; static void do_one_iter( void * data ) { a_thread_data * thread_data = (a_thread_data *)data; int i; EXEC SQL BEGIN DECLARE SECTION; char user[ 20 ]; EXEC SQL END DECLARE SECTION; if( db_init( &thread_data->sqlca ) != 0 ) { for( i = 0; i < thread_data->num_iters; i++ ) { EXEC SQL CONNECT "dba" IDENTIFIED BY "sql"; EXEC SQL SELECT USER INTO :user; EXEC SQL DISCONNECT; } printf( "Thread %d did %d iters successfully\n", thread_data->thread, thread_data->num_iters ); db_fini( &thread_data->sqlca ); } thread_data->done = TRUE; } int main() { int num_threads = 4; int thread; int num_iters = 300; int num_done = 0; a_thread_data *thread_data; thread_data = (a_thread_data *)malloc( sizeof( a_thread_data ) * num_threads ); for( thread = 0; thread < num_threads; thread++ ) { thread_data[ thread ].num_iters = num_iters; thread_data[ thread ].thread = thread; thread_data[ thread ].done = FALSE; if( _beginthread( do_one_iter, 8096, (void *)&thread_data[thread] ) <= 0 ) { printf( "FAILED creating thread.\n" ); return( 1 ); } } while( num_done != num_threads ) { Sleep( 1000 ); num_done = 0; for( thread = 0; thread < num_threads; thread++ ) { if( thread_data[ thread ].done == TRUE ) { num_done++; } } } return( 0 ); } |
Copyright © 2009, iAnywhere Solutions, Inc. - SQL Anywhere 11.0.1 |