DATOR


Groovy를 이용해 멀티스레드로 SQL 실행시키기

Groovy SQL을 둘러봤으니 이번엔 Groovy SQL을 이용해서 만든 스크립트 예제를 하나 보겠습니다. 
아래 Groovy 스크립트는 많은 수의 BR검증SQL에 대해서 멀티스레드를 이용해서 동시에 여러개의 SQL을 실행시키게 만든 스크립트입니다. 데이터베이스의 성능이 받춰주는 만큼 스레드 갯수를 조절해서 실행시키면 SQL이 끝나기를 기다리는 시간을 많이 줄일 수 있습니다. 스레드 갯수는 적절히 조절할 필요가 있습니다. 짧은 코드지만 꽤 다양하게 활용이 가능한 스크립트입니다.

import java.sql.*
import groovy.sql.Sql
import java.util.concurrent.*

/**
 * BR 검증SQL을 일괄 실행시켜서 결과값을 확인하기 위한 클래스이다.
 * 
 * @author hkwee
 * @since  2012-05-03
 */
class ExecBRSql{
	def THREADS = 5
	
	def url = "jdbc:oracle:thin:@127.0.0.1:1521:ora10g"
	def userid = "scott"
	def passwd = "tiger"
	def driver = "oracle.jdbc.driver.OracleDriver"
	
	static void main(String[] args) {
		def execBrSql = new ExecBRSql()
		execBrSql.execute()
	}
	
	private void execute() {
		def sql = Sql.newInstance(url, userid, passwd, driver)
		
		def queue = new ArrayBlockingQueue<String>(1000);
		def pool = Executors.newFixedThreadPool(THREADS)
		
		def nDq = """
				select dq_no, dq_table, br_sql 
				  from n_dq 	
				 order by dq_no
					"""
		
		sql.eachRow(nDq) { row ->
			def sqlDto = new SqlDto()
			sqlDto.no = row.dq_no
			sqlDto.sql = row.br_sql
			
			queue << sqlDto
		}
		
		def item = null
		
		while (item = queue.take()) {
			pool.execute(new ExecuteStatement(item))
			
			if (queue.size() == 0)
				break
		}
		
		pool.shutdown();
	}
}

class ExecuteStatement implements Runnable {
	
	def sqlDto = null	
	def ExecuteStatement(sqlDto) {
		this.sqlDto = sqlDto
	}
	
	@Override
	public void run() {
	def url = "jdbc:oracle:thin:@127.0.0.1:1521:ora10g"
	def userid = "scott"
	def passwd = "tiger"
	def driver = "oracle.jdbc.driver.OracleDriver"

		def sql = Sql.newInstance(url, userid, passwd, driver)			
		def THREAD_NAME = Thread.currentThread().getName()			
		def insertQuery = """insert into temp_n_dq (dq_no, col1, col2, col3, col4, col5, col6, col7, col8, col9, col10)
								values (?,?,?,?,?,?,?,?,?,?,?)"""										
		def vals = new Object[11]		
		try {
			println "[${THREAD_NAME}], ${sqlDto.no} - " + this.sqlDto.sql.replaceAll("\n", "")
			
			sql.query(sqlDto.sql) { rs ->
				vals = new Object[11]
				def meta = rs.metaData
				def isClean = true;
				vals[0] = sqlDto.no
				
				while(rs.next()){
					for (int i = 1; i <= (meta.columnCount > 10 ? 10 : meta.columnCount); i++) {
						vals[i] = rs.getString(i)
					}
					
					sql.executeUpdate(insertQuery, vals)
					isClean = false;
				}
				
				if (isClean) {
					vals[1] = "no data"
					sql.executeUpdate(insertQuery, vals)
				}
			}
		} catch (Exception e) {
			println "[${THREAD_NAME}], ${sqlDto.no} - error : ${e.message}"
			sql.executeUpdate(insertQuery, [sqlDto.no, e.message])
		} finally {
			sql.close()
			println "[${THREAD_NAME}], ${sqlDto.no} - finished .."
		}
	}
}

class SqlDto {
	def no
	def sql
}




Leave Comments

댓글 쓰기 권한이 없습니다. 회원 가입후에 사용 가능합니다