1
votes

I'm trying to add a long list of file into mysql and use spring ACL service with grails to attach permission. So, in my controller i have:

Files.withTransaction {
            Files file = new Files(dataStore:ds,created:new Date(),path:target,name:fileName,contentType:contentType,contentLength:contentLength,isFolder:false).save(flush:true)
            file = Files.lock(file.id)
            filesService.addPermission(file, username ,BasePermission.ADMINISTRATION)
        }

the i have no worries with the Files domain object, it supports huge amount of data ,(specially since i 've disabled versioning in mysql), the problem is on filesService which uses aclUtilService,

@Transactional
    @PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_USER') or hasRole('ROLE_GROUP_OWNER')")
    def addPermission(Files f, String username,Permission permission) {
        aclUtilService.addPermission f,username,permission
    }

Randomly i have the following deadlock (optmistic?)error :

Deadlock found when trying to get lock; try restarting transaction. Stacktrace follows: com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollbackException: Deadlock found when trying to get lock; try restarting transaction at com.mysql.jdbc.Util.handleNewInstance(Util.java:406) at com.mysql.jdbc.Util.getInstance(Util.java:381) at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1045) at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:956) at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3558) at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3490) at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1959) at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2109) at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2648) at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2077) at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2362) at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2280) at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2265) at org.grails.plugins.springsecurity.service.acl.AclService.save(AclService.groovy:330) at org.grails.plugins.springsecurity.service.acl.AclService.createEntries(AclService.groovy:198) at org.grails.plugins.springsecurity.service.acl.AclService.updateAcl(AclService.groovy:176) at GrailsMelodyGrailsPlugin$_closure5_closure18_closure19.doCall(GrailsMelodyGrailsPlugin.groovy:170) at org.grails.plugins.springsecurity.service.acl.AclUtilService.addPermission(AclUtilService.groovy:90) at org.grails.plugins.springsecurity.service.acl.AclUtilService.addPermission(AclUtilService.groovy:67) at GrailsMelodyGrailsPlugin$_closure5_closure18_closure19.doCall(GrailsMelodyGrailsPlugin.groovy:170) at xxxxxxxxxxxxx.FilesService.addPermission(FilesService.groovy:34) at GrailsMelodyGrailsPlugin$_closure5_closure18_closure19.doCall(GrailsMelodyGrailsPlugin.groovy:170) at xxxxxxxxxxxxxQuantumController$_uploadToS3_closure1$$ENzPdDAW.doCall(QuantumController.groovy:87) at org.grails.datastore.gorm.GormStaticApi.withTransaction(GormStaticApi.groovy:686) at xxxxxxxxxxxxx.QuantumController$$ENzPdDAW.uploadToS3(QuantumController.groovy:84) at grails.plugin.cache.web.filter.PageFragmentCachingFilter.doFilter(PageFragmentCachingFilter.java:195) at grails.plugin.cache.web.filter.AbstractFilter.doFilter(AbstractFilter.java:63) at net.bull.javamelody.JspWrapper.invoke(JspWrapper.java:149) at net.bull.javamelody.JdbcWrapper$DelegatingInvocationHandler.invoke(JdbcWrapper.java:259) at net.bull.javamelody.MonitoringFilter.doFilter(MonitoringFilter.java:202) at net.bull.javamelody.MonitoringFilter.doFilter(MonitoringFilter.java:175) at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:895) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:918) at java.lang.Thread.run(Thread.java:680)

Any help please ?

1

1 Answers

0
votes

just encapsulated the transaction in controller and use @Transactional in the service to solve the issue:

Files.withTransaction {
                    Files file = new Files(
...
                    if (file.validate()) {
                        file.save()
                        filesService.addPermission(file,username,BasePermission.ADMINISTRATION)

...}
}