У меня есть фильтр в Grails для захвата всех запросов контроллера и вставки строки в базу данных с именами контроллера, actionName, userId, датой и guid. Это прекрасно работает, но я хотел бы найти способ повысить производительность. Сейчас на все это уходит около 100 миллисекунд, из которых 70-80 мс — на создание инструкции. Я использовал как вставку объекта домена, groovy Sql, так и необработанное соединение/оператор Java. Есть ли более быстрый способ повысить производительность вставки одной записи в фильтр? В качестве альтернативы, есть ли другой шаблон, который можно использовать для вставок? Код (с использованием groovy SQL) Ниже:
class StatsFilters {
def grailsApplication
def dataSource
def filters =
{
logStats(controller:'*', action:'*')
{
before = {
if(controllerName == null || actionName == null)
{
return true
}
def logValue = grailsApplication.config.statsLogging
if(logValue.equalsIgnoreCase("on") && session?.user?.uid != null & session?.user?.uid != "")
{
try{
def start = System.currentTimeMillis()
Sql sql = new Sql(dataSource)
def userId = session.user.uid
final String uuid = "I" + UUID.randomUUID().toString().replaceAll("-","");
String insert = "insert into STATS(ID, CONTROLLER, ACTION, MODIFIED_DATE, USER_ID) values ('${uuid}','${controllerName}','${actionName}',SYSDATE,'${userId}')"
sql.execute(insert)
sql.close()
def end = System.currentTimeMillis()
def total = end - start
println("total " + total)
}
catch(e)
{
log.error("Stats failed to save with exception " + e.getStackTrace())
return true
}
}
return true
}
}
}
}
И мой текущий источник данных
dataSource {
pooled = true
dialect="org.hibernate.dialect.OracleDialect"
properties {
maxActive = 50
maxIdle = 10
initialSize = 10
minEvictableIdleTimeMillis = 1800000
timeBetweenEvictionRunsMillis = 1800000
maxWait = 10000
validationQuery = "select * from resource_check"
testWhileIdle = true
numTestsPerEvictionRun = 3
testOnBorrow = true
testOnReturn = true
}
//loggingSql = true
}
----------------------Решение-------------------------
Решение состояло в том, чтобы просто создать поток и сохранить статистику. Таким образом, время отклика пользователя не влияет, но сохранение выполняется почти в реальном времени. Количество пользователей в этом приложении (корпоративные внутренние, ограниченная группа пользователей) не заслуживает ничего более надежного.
void saveStatData(def controllerName, def actionName, def userId)
{
Thread.start{
Sql sql = new Sql(dataSource)
final String uuid = "I" + UUID.randomUUID().toString().replaceAll("-","");
String insert = "insert into STATS(ID, CONTROLLER, ACTION, MODIFIED_DATE, USER_ID) values ('${uuid}','${controllerName}','${actionName}',SYSDATE,'${userId}')"
sql.execute(insert)
sql.close()
}
}