[Title] Fixed multi-threaded access problem when using sqlite3
authordonghee yang <donghee.yang@samsung.com>
Tue, 30 Oct 2012 01:21:18 +0000 (10:21 +0900)
committerdonghee yang <donghee.yang@samsung.com>
Tue, 30 Oct 2012 01:21:18 +0000 (10:21 +0900)
src/build_server/BuildServer.rb
src/build_server/CommonProject.rb
src/build_server/DistributionManager.rb
src/build_server/JobManager.rb
src/build_server/ProjectManager.rb

index aa7d64fcac6875d964b8f992f8526995f5755c1b..2c77ce53d700a3107a39c583d5b4c006ed36747c 100644 (file)
@@ -29,6 +29,7 @@ Contributors:
 require 'rubygems'
 require 'fileutils'
 require 'dbi'
+require 'thread'
 $LOAD_PATH.unshift File.dirname(__FILE__)
 require "SocketJobRequestListener.rb"
 require "JobManager.rb"
@@ -115,6 +116,7 @@ class BuildServer
                @db_user = nil
                @db_passwd = nil
                @db_version = 1
+               @sqlite3_db_mutex = Mutex.new
 
                #DB upgrade SQL command
                @db_migrate = []
@@ -221,19 +223,16 @@ class BuildServer
 
        def get_remote_servers()
                result = []
-               begin
-                       db = get_db_connection()
+               rows = nil
+               get_db_connection() do |db|
                        rows = db.select_all("SELECT * FROM remote_build_servers")
+               end
+
+               if not rows.nil? then
                        rows.each do |row|
                                svr_ip,svr_port=row['svr_addr'].strip.split(":")
                                result.push RemoteBuildServer.new( svr_ip, svr_port, self )
                        end
-
-               rescue DBI::DatabaseError => e
-                       @log.error "DB failed!"
-                       @log.error e.errstr
-                       @log.error e.backtrace.inspect
-                       return []
                end
 
                return result
@@ -244,24 +243,10 @@ class BuildServer
        def add_remote_server( ip, port )
 
                saddr="#{ip}:#{port}"
-               begin
-                       db = get_db_connection()
-                       db['AutoCommit'] = false
-                       db.transaction do |dbh|
-                               row = dbh.select_one("SELECT * FROM remote_build_servers WHERE svr_addr='#{saddr}'")
-                               if not row.nil? then return false end
-
-                               dbh.do "INSERT INTO remote_build_servers (svr_addr) VALUES ('#{saddr}')"
-                       end
-
-               rescue DBI::DatabaseError => e
-                       @log.error "DB failed!"
-                       @log.error e.errstr
-                       @log.error e.backtrace.inspect
-                       return false
-
-               ensure
-                       db['AutoCommit'] = true if not db.nil?
+               get_db_connection() do |db|
+                       row = db.select_one("SELECT * FROM remote_build_servers WHERE svr_addr='#{saddr}'")
+                       if not row.nil? then return false end
+                       db.do "INSERT INTO remote_build_servers (svr_addr) VALUES ('#{saddr}')"
                end
 
                return true
@@ -271,25 +256,10 @@ class BuildServer
        # remove remote friend server
        def remove_remote_server( ip, port )
                saddr="#{ip}:#{port}"
-               begin
-                       db = get_db_connection()
-                       db['AutoCommit'] = false
-                       db.transaction do |dbh|
-                               row = dbh.select_one("SELECT * FROM remote_build_servers WHERE svr_addr='#{svr_addr}'")
-                               if row.nil? then return false end
-
-                               dbh.do("DELETE FROM remote_build_servers WHERE svr_addr='#{svr_addr}'")
-                       end
-
-               rescue DBI::DatabaseError => e
-                       @log.error "DB failed!"
-                       @log.error e.errstr
-                       @log.error e.backtrace.inspect
-
-                       return false
-
-               ensure
-                       db['AutoCommit'] = true if not db.nil?
+               get_db_connection() do |db|
+                       row = db.select_one("SELECT * FROM remote_build_servers WHERE svr_addr='#{svr_addr}'")
+                       if row.nil? then return false end
+                       db.do("DELETE FROM remote_build_servers WHERE svr_addr='#{svr_addr}'")
                end
 
                return true
@@ -298,18 +268,11 @@ class BuildServer
 
        def get_sync_package_servers()
                result = []
-               begin
-                       db = get_db_connection()
+               get_db_connection() do |db|
                        rows = db.select_all("SELECT * FROM sync_pkg_servers")
                        rows.each do |row|
                                result.push [row['pkgsvr_url'], row['dist_name']]
                        end
-
-               rescue DBI::DatabaseError => e
-                       @log.error "DB failed!"
-                       @log.error e.errstr
-                       @log.error e.backtrace.inspect
-                       return []
                end
 
                return result
@@ -318,24 +281,10 @@ class BuildServer
 
        # add new remote pkg server
        def add_sync_package_server( url, dist )
-               begin
-                       db = get_db_connection()
-                       db['AutoCommit'] = false
-                       db.transaction do |dbh|
-                               row = dbh.select_one("SELECT * FROM sync_pkg_servers WHERE pkgsvr_url='#{url}' and dist_name='#{dist}'")
-                               if not row.nil? then return false end
-
-                               db.do "INSERT INTO sync_pkg_servers (pkgsvr_url,period,dist_name) VALUES('#{url}','#{@pkg_sync_period}','#{dist}')"
-                       end
-
-               rescue DBI::DatabaseError => e
-                       @log.error "DB failed!"
-                       @log.error e.errstr
-                       @log.error e.backtrace.inspect
-                       return false
-
-               ensure
-                       db['AutoCommit'] = true if not db.nil?
+               get_db_connection() do |db|
+                       row = db.select_one("SELECT * FROM sync_pkg_servers WHERE pkgsvr_url='#{url}' and dist_name='#{dist}'")
+                       if not row.nil? then return false end
+                       db.do "INSERT INTO sync_pkg_servers (pkgsvr_url,period,dist_name) VALUES('#{url}','#{@pkg_sync_period}','#{dist}')"
                end
 
                return true
@@ -344,25 +293,10 @@ class BuildServer
 
        # remove remote pkg server
        def remove_sync_package_server( url, dist )
-               begin
-                       db = get_db_connection()
-                       db['AutoCommit'] = false
-                       db.transaction do |dbh|
-                               row = dbh.select_one("SELECT * FROM sync_pkg_servers WHERE pkgsvr_url='#{url}' and dist_name='#{dist}'")
-                               if row.nil? then return false end
-
-                               dbh.do("DELETE FROM sync_pkg_servers WHERE pkgsvr_url='#{url}' and dist_name='#{dist}'")
-                       end
-
-               rescue DBI::DatabaseError => e
-                       @log.error "DB failed!"
-                       @log.error e.errstr
-                       @log.error e.backtrace.inspect
-
-                       return false
-
-               ensure
-                       db['AutoCommit'] = true if not db.nil?
+               get_db_connection() do |db|
+                       row = db.select_one("SELECT * FROM sync_pkg_servers WHERE pkgsvr_url='#{url}' and dist_name='#{dist}'")
+                       if row.nil? then return false end
+                       db.do("DELETE FROM sync_pkg_servers WHERE pkgsvr_url='#{url}' and dist_name='#{dist}'")
                end
 
                return true
@@ -371,18 +305,11 @@ class BuildServer
 
        def supported_os_list
                result = []
-               begin
-                       db = get_db_connection()
+               get_db_connection() do |db|
                        rows = db.select_all("SELECT * FROM supported_os")
                        rows.each do |row|
                                result.push row['name']
                        end
-
-               rescue DBI::DatabaseError => e
-                       @log.error "DB failed!"
-                       @log.error e.errstr
-                       @log.error e.backtrace.inspect
-                       return []
                end
 
                return result
@@ -392,24 +319,10 @@ class BuildServer
        # add new target OS.
        # If already exist, return false , otherwise true
        def add_supported_os( os_name )
-               begin
-                       db = get_db_connection()
-                       db['AutoCommit'] = false
-                       db.transaction do |dbh|
-                               row = dbh.select_one("SELECT * FROM supported_os WHERE name='#{os_name}'")
-                               if not row.nil? then return false end
-
-                               dbh.do "INSERT OR REPLACE INTO supported_os VALUES ('#{os_name}')"
-                       end
-
-               rescue DBI::DatabaseError => e
-                       @log.error "DB failed!"
-                       @log.error e.errstr
-                       @log.error e.backtrace.inspect
-                       return false
-
-               ensure
-                       db['AutoCommit'] = true if not db.nil?
+               get_db_connection() do |db|
+                       row = db.select_one("SELECT * FROM supported_os WHERE name='#{os_name}'")
+                       if not row.nil? then return false end
+                       db.do "INSERT OR REPLACE INTO supported_os VALUES ('#{os_name}')"
                end
 
                return true
@@ -419,25 +332,10 @@ class BuildServer
 
        # remove target OS.
        def remove_supported_os( os_name )
-               begin
-                       db = get_db_connection()
-                       db['AutoCommit'] = false
-                       db.transaction do |dbh|
-                               row = dbh.select_one("SELECT * FROM supported_os WHERE name='#{os_name}'")
-                               if row.nil? then return false end
-
-                               dbh.do("DELETE FROM supported_os WHERE name='#{os_name}'")
-                       end
-
-               rescue DBI::DatabaseError => e
-                       @log.error "DB failed!"
-                       @log.error e.errstr
-                       @log.error e.backtrace.inspect
-
-                       return false
-
-               ensure
-                       db['AutoCommit'] = true if not db.nil?
+               get_db_connection() do |db|
+                       row = db.select_one("SELECT * FROM supported_os WHERE name='#{os_name}'")
+                       if row.nil? then return false end
+                       db.do("DELETE FROM supported_os WHERE name='#{os_name}'")
                end
 
                return true
@@ -572,11 +470,7 @@ class BuildServer
 
 
        def create_db()
-               result = true
-               # create DB
-               begin
-                       #DB open
-                       db = get_db_connection()
+               result = get_db_connection() do |db|
                        case @db_dsn
                        when /^SQLite3:/ then inc="AUTOINCREMENT"
                        when /^Mysql:/ then inc="AUTO_INCREMENT"
@@ -613,55 +507,62 @@ class BuildServer
 
                        # JOBS
                        db.do "CREATE TABLE jobs(id INTEGER PRIMARY KEY, jtype VARCHAR(32), os_name VARCHAR(32), user_id INTEGER, parent_job_id INTEGER, status VARCHAR(32), prj_id INTEGER, dist_name VARCHAR(32), start_time VARCHAR(32), end_time VARCHAR(32) )"
-
-               rescue DBI::DatabaseError => e
-                       puts "DB Creation failed!"
-                       puts e.errstr
-                       @log.error e.backtrace.inspect
-                       result = false
                end
 
                return result
        end
 
 
-       def get_db_connection()
-               if not @db.nil? and @db.connected? then return @db end
-               if not @db.nil? then
-                       @db.disconnect
-                       @db = nil
-               end
-
+       def get_db_connection(transaction=true)
                begin
-                       db = DBI.connect("DBI:#{@db_dsn}", @db_user, @db_passwd)
+                       if @db_dsn =~ /^SQLite3:/ then
+                               @sqlite3_db_mutex.lock
+                               @db = DBI.connect("DBI:#{@db_dsn}", @db_user, @db_passwd)
+                       else
+                               if @db.nil? or not @db.connected? then
+                                       @db = DBI.connect("DBI:#{@db_dsn}", @db_user, @db_passwd)
+                               end
+                       end
+                       if transaction then
+                               @db['AutoCommit'] = false
+                               begin
+                                       @db.transaction do |dbh|
+                                               yield dbh if block_given?
+                                       end
+                               ensure
+                                       @db['AutoCommit'] = true
+                               end
+                       else
+                               yield @db if block_given?
+                       end
+
+                       return true
 
                rescue DBI::DatabaseError => e
                        @log.error "DB loading failed!"
                        @log.error e.errstr
                        @log.error e.backtrace.inspect
-                       db.disconnect if db
 
-                       return nil
+               ensure
+                       if @db_dsn =~ /^SQLite3:/ then
+                               @db.disconnect if @db
+                               @db = nil
+                               @sqlite3_db_mutex.unlock
+                       end
                end
 
-               @db = db
-               return @db
+               return false
        end
 
 
        def check_user_id_from_email(user_email)
-               begin
-                       db = get_db_connection()
+               get_db_connection() do |db|
                        row = db.select_one("SELECT * FROM users WHERE email='#{user_email}'")
                        if not row.nil?  then
                                return row['id']
                        else
                                return -1 
                        end
-               rescue DBI::DatabaseError => e
-                       @log.error "DB failed!"
-                       @log.error e.errstr
-                       @log.error e.backtrace.inspect
                end
 
                return -1
@@ -669,18 +570,13 @@ class BuildServer
 
 
        def qualify_admin_to_access(prj_id)
-               begin
-                       db = get_db_connection()
+               get_db_connection() do |db|
                        row = db.select_one("SELECT * FROM group_project_accesses WHERE group_id=0 and prj_id=#{prj_id}")
                        if row.nil?  then
                                db.do("INSERT INTO group_project_accesses VALUES(0, #{prj_id}, 'TRUE')")
                        else
                                db.do("UPDATE group_project_accesses SET build='TRUE' WHERE group_id=0 and prj_id=#{prj_id}")
                        end
-               rescue DBI::DatabaseError => e
-                       @log.error "DB failed!"
-                       @log.error e.errstr
-                       @log.error e.backtrace.inspect
                end
        end
 end
index 97fc30bbebc7a99475f6bbb0e897811a0495c970..4bed058f9fb4fd88e4bad5e60b661cf521f47930 100644 (file)
@@ -89,21 +89,8 @@ class CommonProject
                @source_info[ver] = info
 
                # save to db
-               begin
-                       db = @server.get_db_connection()
-                       db['AutoCommit'] = false
-                       db.transaction do |dbh|
-                               save_source_info_internal(ver, info, dbh)
-                       end
-
-               rescue DBI::DatabaseError => e
-                       @server.log.error "DB update failed!"
-                       @server.log.error e.errstr
-                       @server.log.error e.backtrace.inspect
-                       return false
-
-               ensure
-                       db['AutoCommit'] = true if not db.nil?
+               @server.get_db_connection() do |db|
+                       save_source_info_internal(ver, info, db)
                end
        end
 
@@ -125,21 +112,8 @@ class CommonProject
                @package_info[ver].push [pkg_name, pkg_os]
 
                # save to db
-               begin
-                       db = @server.get_db_connection()
-                       db['AutoCommit'] = false
-                       db.transaction do |dbh|
-                               save_package_info_internal(ver, pkg_name, pkg_os, dbh)
-                       end
-
-               rescue DBI::DatabaseError => e
-                       @server.log.error "DB update failed!"
-                       @server.log.error e.errstr
-                       @server.log.error e.backtrace.inspect
-                       return false
-
-               ensure
-                       db['AutoCommit'] = true if not db.nil?
+               @server.get_db_connection() do |db|
+                       save_package_info_internal(ver, pkg_name, pkg_os, db)
                end
        end
 
index 06d5df9c0eb05ab85df217784eedf89661332154..7b4dec2836092a8033fb56d4a7955548db34d7bd 100644 (file)
@@ -130,20 +130,8 @@ class DistributionManager
        # get distribution
        def get_distribution(name)
                # conntect DB
-               begin
-                       db = @server.get_db_connection()
-                       db['AutoCommit'] = false
-                       db.transaction do |dbh|
-                               return get_distribution_internal(name, dbh)
-                       end
-
-               rescue DBI::DatabaseError => e
-                       @server.log.error "DB loading failed!"
-                       @server.log.error e.errstr
-                       @server.log.error e.backtrace.inspect
-
-               ensure
-                       db['AutoCommit'] = true if not db.nil?
+               @server.get_db_connection() do |db|
+                       return get_distribution_internal(name, db)
                end
 
                return nil
@@ -157,28 +145,14 @@ class DistributionManager
 
        # add
        def add_distribution(name, pkgsvr_url, pkgsvr_ip, pkgsvr_port)
-               begin
-                       # open DB
-                       db = @server.get_db_connection()
-                       db['AutoCommit'] = false
-                       db.transaction do |dbh|
-                               if not get_distribution_internal(name, dbh).nil? then
-                                       @server.log.info "The distribution \"#{name}\" already exists on server"
-                                       @server.log.error "Adding distribution failed!"
-                                       return false
-                               end
-                               new_dist = PackageDistribution.new(name, pkgsvr_url, pkgsvr_ip, pkgsvr_port, "OPEN")
-                               new_dist.save(dbh)
+               @server.get_db_connection() do |db|
+                       if not get_distribution_internal(name, db).nil? then
+                               @server.log.info "The distribution \"#{name}\" already exists on server"
+                               @server.log.error "Adding distribution failed!"
+                               return false
                        end
-
-               rescue DBI::DatabaseError => e
-                       @server.log.error "DB update failed!"
-                       @server.log.error e.errstr
-                       @server.log.error e.backtrace.inspect
-                       return false
-
-               ensure
-                       db['AutoCommit'] = true if not db.nil?
+                       new_dist = PackageDistribution.new(name, pkgsvr_url, pkgsvr_ip, pkgsvr_port, "OPEN")
+                       new_dist.save(db)
                end
                
                @server.log.info "Added a new distribution \"#{name}\""
@@ -189,51 +163,24 @@ class DistributionManager
        # remove
        def remove_distribution(name)
 
-               begin
-                       # open DB
-                       db = @server.get_db_connection()
-                       db['AutoCommit'] = false
-                       db.transaction do |dbh|
-                               dist = get_distribution_internal(name, dbh)
-                               if dist.nil? then
-                                       @server.log.error "The distribution \"#{name}\" does not exists on server"
-                                       @server.log.error "Removing distribution failed!"
-                                       return false
-                               end
-                               dist.unload(dbh)
+               result = @server.get_db_connection() do |db|
+                       dist = get_distribution_internal(name, db)
+                       if dist.nil? then
+                               @server.log.error "The distribution \"#{name}\" does not exists on server"
+                               @server.log.error "Removing distribution failed!"
+                               return false
                        end
-
-               rescue DBI::DatabaseError => e
-                       @server.log.error "DB update failed!"
-                       @server.log.error e.errstr
-                       @server.log.error e.backtrace.inspect
-                       return false
-
-               ensure
-                       db['AutoCommit'] = true if not db.nil?
+                       dist.unload(db)
                end
 
                @server.log.info "Removed the distribution \"#{name}\""
-               return true
+               return result
        end
 
 
        def get_first_distribution()
-               begin
-                       # open DB
-                       db = @server.get_db_connection()
-                       db['AutoCommit'] = false
-                       db.transaction do |dbh|
-                               return PackageDistribution.load_first(dbh)
-                       end
-
-               rescue DBI::DatabaseError => e
-                       @server.log.error "DB loading failed!"
-                       @server.log.error e.errstr
-                       @server.log.error e.backtrace.inspect
-
-               ensure
-                       db['AutoCommit'] = true if not db.nil?
+               @server.get_db_connection() do |db|
+                       return PackageDistribution.load_first(db)
                end
 
                return nil
@@ -241,21 +188,8 @@ class DistributionManager
 
 
        def get_all_distributions()
-               begin
-                       # open DB
-                       db = @server.get_db_connection()
-                       db['AutoCommit'] = false
-                       db.transaction do |dbh|
-                               return PackageDistribution.load_all(dbh)
-                       end
-
-               rescue DBI::DatabaseError => e
-                       @server.log.error "DB loading failed!"
-                       @server.log.error e.errstr
-                       @server.log.error e.backtrace.inspect
-
-               ensure
-                       db['AutoCommit'] = true if not db.nil?
+               @server.get_db_connection() do |db|
+                       return PackageDistribution.load_all(db)
                end
 
                return []
@@ -263,36 +197,23 @@ class DistributionManager
 
 
        def set_distribution_lock(name, value=true)
-               begin
-                       # open DB
-                       db = @server.get_db_connection()
-                       db['AutoCommit'] = false
-                       db.transaction do |dbh|
-                               # check already exist
-                               dist = get_distribution_internal(name, dbh)
-                               if dist.nil? then return false end
-
-                               dist.status = value ? "LOCKED" : "OPEN"
-                               dist.save(dbh)
-                       end
-
-               rescue DBI::DatabaseError => e
-                       @server.log.error "DB update failed!"
-                       @server.log.error e.errstr
-                       @server.log.error e.backtrace.inspect
-                       return false
+               result = @server.get_db_connection() do |db|
+                       # check already exist
+                       dist = get_distribution_internal(name, db)
+                       if dist.nil? then return false end
 
-               ensure
-                       db['AutoCommit'] = true if not db.nil?
-               end
-       
-               if value then   
-                       @server.log.info "The distribution \"#{name}\" is locked!"
-               else
-                       @server.log.info "The distribution \"#{name}\" is unlocked!"
+                       dist.status = value ? "LOCKED" : "OPEN"
+                       dist.save(db)
                end
+               if result then 
+                       if value then   
+                               @server.log.info "The distribution \"#{name}\" is locked!"
+                       else
+                               @server.log.info "The distribution \"#{name}\" is unlocked!"
+                       end
+               end     
 
-               return true
+               return result
        end
 
        #END
index 385beebecde4e35b15c094df04e9b94defad4b9d..9043a0b0be3b3619dbd093f639a6f75ba56059d7 100644 (file)
@@ -439,28 +439,20 @@ class JobManager
                                result.push job
                        end
                end
+
                return result
        end
 
 
        def save_job_status(job)
-               begin
-                       db = @server.get_db_connection()
-                       db['AutoCommit'] = false
-                       db.transaction do |dbh|
-                               return job.save(dbh)
-                       end
-
-               rescue DBI::DatabaseError => e
-                       @server.log.error "DB failed!"
-                       @server.log.error e.errstr
-                       @server.log.error e.backtrace.inspect
-
-               ensure
-                       db['AutoCommit'] = true if not db.nil?
+               result = @server.get_db_connection() do |db|
+                       return job.save(db)
                end
+
+               return result
        end
 
+
        protected
        # select the job whith no build-dependency problem
        # if "check_dep_wait" is true, it will check the build dependency
index 07310914910235e7f38d074de4e65ea20ab9abd6..c216e8a1ed55f79b7f38c84a0cc61bb0de657156 100644 (file)
@@ -55,20 +55,8 @@ class ProjectManager
 
        # get_project of the name
        def get_project(name, dist_name)
-               begin
-                       db = @server.get_db_connection()
-                       db['AutoCommit'] = false
-                       db.transaction do |dbh|
-                               return get_project_internal(name, dist_name, dbh)
-                       end
-
-               rescue DBI::DatabaseError => e
-                       @server.log.error "DB failed!"
-                       @server.log.error e.errstr
-                       @server.log.error e.backtrace.inspect
-
-               ensure
-                       db['AutoCommit'] = true if not db.nil?
+               @server.get_db_connection() do |db|
+                       return get_project_internal(name, dist_name, db)
                end
 
                return nil
@@ -78,33 +66,21 @@ class ProjectManager
        def get_all_projects()
                result = []
 
-               begin
-                       db = @server.get_db_connection()
-                       db['AutoCommit'] = false
-
-                       db.transaction do |dbh|
-                               rows = dbh.select_all("SELECT * FROM projects")
-                               rows.each do |row|
-                                       prj_name = row['name']
-                                       prj_dist = row['dist_name']
-                                       prj_type = row['ptype']
-                                       if prj_type == "GIT" then
-                                               result.push GitBuildProject.load(prj_name, prj_dist, @server, dbh)
-                                       else
-                                               result.push BinaryUploadProject.load(prj_name, prj_dist, @server, dbh)
-                                       end
+               @server.get_db_connection() do |db|
+                       rows = db.select_all("SELECT * FROM projects")
+                       rows.each do |row|
+                               prj_name = row['name']
+                               prj_dist = row['dist_name']
+                               prj_type = row['ptype']
+                               if prj_type == "GIT" then
+                                       prj = GitBuildProject.load(prj_name, prj_dist, @server, db)
+                               else
+                                       prj = BinaryUploadProject.load(prj_name, prj_dist, @server, db)
                                end
+                               if not prj.nil? then result.push prj end
                        end
                        
                        return result
-       
-               rescue DBI::DatabaseError => e
-                       @server.log.error "DB failed!"
-                       @server.log.error e.errstr
-                       @server.log.error e.backtrace.inspect
-
-               ensure
-                       db['AutoCommit'] = true if not db.nil?
                end
 
                return result
@@ -113,120 +89,85 @@ class ProjectManager
 
        def add_git_project(name, repos, branch, passwd, os_list, dist_name)
                new_prj = nil
-               begin
-                       db = @server.get_db_connection()
-                       db['AutoCommit'] = false
-                       db.transaction do |dbh|
-                               prj = get_project_internal(name, dist_name, dbh)
-                               if not prj.nil? then
-                                       @server.log.error "Adding project failed!: the project \"#{name}\"(#{dist_name}) already exists"
-                                       return false
-                               end
+               result = @server.get_db_connection() do |db|
+                       prj = get_project_internal(name, dist_name, db)
+                       if not prj.nil? then
+                               @server.log.error "Adding project failed!: the project \"#{name}\"(#{dist_name}) already exists"
+                               return false
+                       end
                                
-                               # create new object
-                               new_prj = GitBuildProject.new(name, @server, os_list, dist_name, repos, branch)
-                               if not passwd.nil? and not passwd.empty? then
-                                       new_prj.passwd = passwd
-                               end
-
-                               # save to db
-                               new_prj.save(dbh)
+                       # create new object
+                       new_prj = GitBuildProject.new(name, @server, os_list, dist_name, repos, branch)
+                       if not passwd.nil? and not passwd.empty? then
+                               new_prj.passwd = passwd
                        end
-       
-               rescue DBI::DatabaseError => e
-                       @server.log.error "DB failed!"
-                       @server.log.error e.errstr
-                       @server.log.error e.backtrace.inspect
-
-                       return false
-               ensure
-                       db['AutoCommit'] = true if not db.nil?
+
+                       # save to db
+                       new_prj.save(db)
                end
 
-               # authorize admin to access
-               @server.qualify_admin_to_access(new_prj.get_project_id())
+               if result then 
+                       # authorize admin to access
+                       @server.qualify_admin_to_access(new_prj.get_project_id())
+                       @server.log.info "Added new GIT project \"#{name}\"(#{dist_name})"
+               end
 
-               @server.log.info "Added new GIT project \"#{name}\"(#{dist_name})"
-               return true
+               return result
        end
 
 
        def add_binary_project(name, pkg_name, passwd, os_list, dist_name)
                new_prj = nil
-               begin
-                       db = @server.get_db_connection()
-                       db['AutoCommit'] = false
-                       db.transaction do |dbh|
-                               prj = get_project_internal(name, dist_name, dbh)
-                               if not prj.nil? then
-                                       @server.log.error "Adding project failed!: the project \"#{name}\"(#{dist_name}) already exists"
-                                       return false
-                               end
-                               
-                               # create new object
-                               new_prj = BinaryUploadProject.new(name, @server, os_list, dist_name, pkg_name)
-                               if not passwd.nil? and not passwd.empty? then
-                                       new_prj.passwd = passwd
-                               end
-
-                               # save to db
-                               new_prj.save(dbh)
-
-                               # init
-                               new_prj.init()
+               result = @server.get_db_connection() do |db|
+                       prj = get_project_internal(name, dist_name, db)
+                       if not prj.nil? then
+                               @server.log.error "Adding project failed!: the project \"#{name}\"(#{dist_name}) already exists"
+                               return false
                        end
+                       
+                       # create new object
+                       new_prj = BinaryUploadProject.new(name, @server, os_list, dist_name, pkg_name)
+                       if not passwd.nil? and not passwd.empty? then
+                               new_prj.passwd = passwd
+                       end
+
+                       # save to db
+                       new_prj.save(db)
 
-               rescue DBI::DatabaseError => e
-                       @server.log.error "DB failed!"
-                       @server.log.error e.errstr
-                       @server.log.error e.backtrace.inspect
+                       # init
+                       new_prj.init()
+               end
 
-                       return false
-               ensure
-                       db['AutoCommit'] = true if not db.nil?
+               if result then
+                       # authorize admin to access
+                       @server.qualify_admin_to_access(new_prj.get_project_id())
+                       @server.log.info "Added new BINARY project \"#{name}\"(#{dist_name})"
                end
 
-               # authorize admin to access
-               @server.qualify_admin_to_access(new_prj.get_project_id())
-       
-               @server.log.info "Added new BINARY project \"#{name}\"(#{dist_name})"
-               return true
+               return result
        end
 
 
        def remove_project( name, dist_name )
 
-               begin
-                       # open DB
-                       db = @server.get_db_connection()
-                       db['AutoCommit'] = false
-                       db.transaction do |dbh|
-                               prj = get_project_internal(name, dist_name, dbh)
-                               if prj.nil? then
-                                       @server.log.error "The project \"#{name}\"(#{dist_name}) does not exists on server"
-                                       @server.log.error "Removing project failed!"
-                                       return false
-                               end
-                               # unload from DB
-                               prj.unload(dbh)
-
-                               # remove project directory
-                               FileUtils.rm_rf prj.path
+               result = @server.get_db_connection() do |db|
+                       prj = get_project_internal(name, dist_name, db)
+                       if prj.nil? then
+                               @server.log.error "The project \"#{name}\"(#{dist_name}) does not exists on server"
+                               @server.log.error "Removing project failed!"
+                               return false
                        end
+                       # unload from DB
+                       prj.unload(db)
 
-
-               rescue DBI::DatabaseError => e
-                       @server.log.error "DB update failed!"
-                       @server.log.error e.errstr
-                       @server.log.error e.backtrace.inspect
-                       return false
-
-               ensure
-                       db['AutoCommit'] = true if not db.nil?
+                       # remove project directory
+                       FileUtils.rm_rf prj.path
                end
 
-               @server.log.info "Removed the project \"#{name}\"(#{dist_name})"
-               return true
+               if result then
+                       @server.log.info "Removed the project \"#{name}\"(#{dist_name})"
+               end
+               return result
        end